【问题标题】:Hibernate - generated valueHibernate - 生成的值
【发布时间】:2016-08-13 01:57:33
【问题描述】:

我是hibernate的新手,正在玩它。对于实体中的唯一字段,我正在为其设置 @GeneratedValue 注释。假设我有两个实体,用户和公司,并且都具有带有 @GeneratedValue 注释的唯一 ID。当我使用休眠会话工厂保存这两个实体时,生成的 id 分别为 1 和 2,这两个实体应该是 1。下次我保存两者时,生成的 id 是 3 和 4 。 所以我的猜测是,@GeneratedValue 在数据库级别而不是表级别工作。如何使它成为表级?

添加一些代码和配置。

用户实体

@Entity
@Table(name="user")
public class User {
    @Id
    @GeneratedValue
    @Column(name = "id")
    private Integer id;

}

公司实体

@Entity
@Table(name="company")

public class Company {
 @Id
 @GeneratedValue
 @Column(name = "id")
 private Integer id;
}

使用休眠会话保存

Session session = sessionFactory.getCurrentSession();
    User user = new User();

    session.save(user);

    Company company = new Company();
    session.save(company);

结果

mysql> 从用户中选择 *;
+-----+ |编号 | +-----+ | 234 | +-----+

mysql> select * from company;
+-----+ |编号 | +-----+ | 235 | +-----+

对于记录,我使用 hibernate-jpa-2.1-api ( 1.0.0.Draft-16 ) 和 hibernate 5。

【问题讨论】:

  • 默认情况下它实际上应该为两个实体生成 1。请向我们展示您的配置和一些代码。

标签: java mysql hibernate


【解决方案1】:

@GenerateValue 注释有一个名为strategy 的属性,它可以包含以下策略之一来生成主键的值:

  • GenerationType.AUTO
  • GenerationType.IDENTITY
  • GenerationType.SEQUENCE
  • GenerationType.TABLE

GenerationType.AUTO 使用数据库的全局数字生成器,它是默认值,所以如果你只在变量中定义@GenerateValue,你就会有这种行为。

我建议您使用列表中的其他一个来获得您期望的结果。例如,GenerationType.IDENTITY 允许您使用表中的值生成键,只有当主键是自动生成的类型。例如在 Postgres 中,您可以使用数据类型 SERIAL 并使用它来生成键的值。

【讨论】:

  • 如果我使用它,则不会生成 id,并且在保存时出现“字段 'id' 没有默认值”错误。代码:@Id @GeneratedValue(strategy=GenerationType.IDENTITY) @Column(name = "id") private Integer id;
  • 正如我在回复中所说的,数据库中的主键数据类型必须是自动生成的类型,这里有一些 RDBMS 中自动生成类型的示例link
  • 仅供参考,该字段具有 AUTO_INCREMENT 选项。由于验证本身失败,Hibernate 不允许保存。
猜你喜欢
  • 2012-06-06
  • 2013-03-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-09-25
  • 1970-01-01
  • 2019-08-01
  • 1970-01-01
相关资源
最近更新 更多