Search code examples
javahibernatepostgresqlhibernate-annotations

Issues with postgres id generation and hibernate


For some reason when I insert to database from application id is always 0. This is table used for spring security auth table users, copied from pgadmin II:

 id serial NOT NULL,
  username character varying(100),
  password character varying(200),
  groupfk integer,
  CONSTRAINT users_pk PRIMARY KEY (id ),
  CONSTRAINT users_groupfk_fkey FOREIGN KEY (groupfk)
  REFERENCES groups (id) MATCH SIMPLE
  ON UPDATE NO ACTION ON DELETE NO ACTION

I have a following in my User domain class, relevant ID part :

    @Id
    @Column(name = "id", columnDefinition = "serial")
    @Generated(GenerationTime.INSERT)
    public int getId() {
        return id;
    }

    @ManyToOne
@JoinColumn(name = "groupfk")
public Group getGroup() {
    return group;
}

public void setGroup(Group group) {
    this.group = group;
}

So I'm inserting user like this :

User user = new User();
        user.setPassword(password);
        user.setUsername(username);

        Group group = new Group();
        group.setId(usergroup);
        user.setGroup(group);
                dao.saveUser(user);

Dao method impl :

public void save(User user) {
        Session session = sessionFactory.getCurrentSession();
        session.save(user);
    }

So here is the exception I get :

Could not execute JDBC batch update; SQL [insert into users (groupfk, password, username, id) values (?, ?, ?, ?)]; constraint [null]; nested exception is org.hibernate.exception.ConstraintViolationException: Could not execute JDBC batch update

Real query :

Batch entry 0 insert into users (groupfk, password, username, id) values ('1', '098f6bcd4621d373cade4e832627b4f6', 'test3', '0') was aborted.  Call getNextException to see the cause.

So I inserted previous user with id 0 and it was successful. And I tried to insert another one but because it had the same ID this error occurred.

Normally if I try to insert it with sql trough sql client (pgadmin) it works, this works as expected :

insert into users (username, password, groupfk) VALUES ('test', 'c20ad4d76fe97759aa27a0c99bff6710',1);

So hibernate for some reason doesn't generate my id appropriately, the truth is if the above statement is working it shouldn't generate it at all.

What do I do?


Solution

  • Your ID should be an Integer, not an int. Everytime you create an instance of your class, it initializes the value of this.id to 0. Hibernate then will think of this object as already being persisted, but disconnected. You want it to be treated as transient, which is indicated by having a null ID. See a discussion of Hibernate objects states in the manual.

    When you session.save(user), Hibernate will see the ID is null, realize the object is transient, generate an ID for it, and save it.