【问题标题】:Issues with postgres id generation and hibernatepostgres id 生成和休眠的问题
【发布时间】:2012-11-15 16:17:27
【问题描述】:

由于某种原因,当我从应用程序 id 插入数据库时​​,它始终为 0。这是用于 spring security auth 表用户的表,从 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

我的用户域类中有以下相关 ID 部分:

    @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;
}

所以我像这样插入用户:

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

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

道法实现:

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

所以这是我得到的例外:

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

真实查询:

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

所以我插入了以前的用户,ID 为 0,它成功了。我试图插入另一个,但因为它具有相同的 ID,所以发生了这个错误。

通常,如果我尝试使用 sql 槽 sql 客户端 (pgadmin) 插入它,它可以正常工作,这可以按预期工作:

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

因此,由于某种原因,hibernate 无法正确生成我的 id,事实是,如果上述语句有效,则根本不应该生成它。

我该怎么办?

【问题讨论】:

    标签: java hibernate postgresql hibernate-annotations


    【解决方案1】:

    您的 ID 应该是 Integer,而不是 int。每次创建类的实例时,它会将 this.id 的值初始化为 0。Hibernate 会认为该对象已经被持久化,但已断开连接。您希望它被视为瞬态的,这由一个空 ID 表示。请参阅Hibernate objects states in the manual 的讨论。

    当你session.save(user)时,Hibernate 会看到 ID 为 null,意识到对象是瞬态的,为它生成一个 ID,并保存它。

    【讨论】:

    • 您还需要使用IDENTITY 生成策略,而不是AUTO
    • @CraigRinger 我认为 Postgres 需要 SEQUENCE 如果你要指定它,而不是 IDENTITY。见docs.jboss.org/hibernate/orm/3.3/reference/en/html/…。如果您不指定,我相信 Hibernate 会为 Postgres 方言选择 SEQUENCE。
    • 我指的是 JPA 身份注释,因为那是帖子使用的。在 JPA 中,IDENTITY 将使用数据库的标识列(在 PostgreSQL 中为串行)。如果您使用SEQUENCE,那么 Hibernate 将使用共享的hibernate_sequence,除非您还为每个标识列定义了SequenceGenerator 并覆盖其获取大小。与仅使用 IDENTITY 获得相同效果相比,这是不必要的冗长。
    • 现在,如果 Hibernate 是唯一使用数据库的应用程序,则可以使用共享的 hibernate_sequence - 但在这种情况下,您应该使用 integer 列而不是 serial 来消除混淆和未使用的序列。
    猜你喜欢
    • 1970-01-01
    • 2011-03-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-06-30
    • 1970-01-01
    相关资源
    最近更新 更多