【问题标题】:Primitive or wrapper for hibernate primary keys休眠主键的原语或包装器
【发布时间】:2011-04-01 22:29:02
【问题描述】:

我一直在看各种hibernate教程和示例,对于它们的身份/主键属性,有些使用Java原始类型,有些使用包装类型,即;

 private int id; 

 private Integer id;

我为什么以及何时将一个而不是另一个用于实体键?

【问题讨论】:

    标签: java hibernate orm


    【解决方案1】:

    从 Hibernate 的角度来看,它不会改变任何东西,因为 Hibernate 使用相同的 Hibernate 类型来表示它们。

    但是,正如 Bytecode Ninja 所指出的,您无法将原始 int 0 的默认值与分配的 0 区分开来,而 nullnull id 总是意味着一个新实体),这就是为什么我更喜欢使用可为空的包装类型。

    这是 Hibernate 的建议。来自参考文档:

    4.1.2. Provide an identifier property (optional)

    Cat 有一个名为 id 的属性。这 属性映射到主键 数据库表的列。这 属性可能已被调用 任何东西,它的类型可能是 任何原始类型,任何原始类型 “包装器”类型,java.lang.String 或 java.util.日期。如果你的遗产 数据库表有复合键,你 可以使用用户定义的类 这些类型的属性(参见 稍后关于复合标识符的部分 在章节中。)

    标识符属性是严格的 可选的。你可以把它们关掉,然后 让 Hibernate 跟踪对象 内部标识符。我们不 不过推荐这个。

    事实上,有些功能是 仅适用于声明的类 标识符属性:

    • 分离对象的可传递重新附加(级联更新或级联 合并) - 见第 10.11 节, “传递持久性”
    • Session.saveOrUpdate()
    • Session.merge()

    我们建议您声明 一致命名的标识符 持久类的属性和 您使用可空值(即 非原始)类型。

    我实际上在我的基类中利用了这一点:

    @MappedSuperclass
    public class BaseEntity implements Serializable {
        private static final long serialVersionUID = 1L;
        private Long id;
    
        @Id
        @GeneratedValue(strategy = GenerationType.AUTO)
        public Long getId() {
            return id;
        }
    
        public void setId(Long id) {
            this.id = id;
        }
    
        @Transient
        public boolean isNew() {
            return (this.id == null);
        }
    }
    

    【讨论】:

    • 我同意如果他想使用原始类型,他也可以使用Integer进行封装
    • 但是不会每次从DB中读取这样的实体对象时都会创建包装器对象,最终强调GC吗?那么在我们知道主键不能为 0 的情况下使用原语会更好吗?
    • 这仍然是 Hibernate 5.1 的建议,但现在在“2.5.5。提供标识符属性”部分中
    【解决方案2】:

    我更喜欢使用包装类型,因为否则,当我们使用原始类型时,主键 id 将默认设置为 00 可能是实际 id 列的值在实体的相应表中,这有时会导致难以查明错误。

    但是使用包装器,id 的默认值将是 null,并且主键列不能有 null 值,因此您无法更新其 id 值未设置的实体具有应用程序逻辑的有效值。

    【讨论】:

    • 是否总是需要通过应用逻辑设置id?当使用包装器作为主键时,hibernate 无法在持久化新对象的同时找出下一个 id 吗?
    【解决方案3】:

    您可以将主键指定为原语或包装器。由于通常不需要 Integer 的优点,因此最好使用 int 保持简单。

    更多信息请访问oracle.com

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-03-21
      • 2012-03-15
      • 2012-01-25
      • 2017-08-04
      • 1970-01-01
      • 1970-01-01
      • 2011-05-17
      • 2015-12-09
      相关资源
      最近更新 更多