hibernate主键的原语或包装器

时间:2010-08-21 00:52:08

标签: java hibernate orm

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

 private int id; 

VS

 private Integer id;

为什么以及何时使用其中一个,实体密钥?

3 个答案:

答案 0 :(得分:32)

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

然而,正如Bytecode Ninja所指出的那样,你无法区分原始int 0的默认值和指定的0,而null不存在歧义。 (null id总是表示新实体),这就是我更喜欢使用可空包装类型的原因。

这是Hibernate的推荐。参考文献:

  

4.1.2. Provide an identifier property (optional)

     

Cat有一个名为id的属性。这个   属性映射到主键   数据库表的列。该   属性可能已被调用   什么,它的类型可能是   任何原始类型,任何原语   “wrapper”类型,java.lang.String或   java.util.Date。如果你的遗产   数据库表有复合键,你   可以使用用户定义的类   这些类型的属性(见   稍后有关复合标识符的部分   在本章。)

     

标识符属性是严格的   可选的。你可以把它们关掉   让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);
    }
}

答案 1 :(得分:9)

我更喜欢使用包装器类型,否则,当我们使用基元类型时,默认情况下主键id将设置为0,而0可能是id的值实体的相应表中的实际id列,这有时会导致难以查明错误。

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

答案 2 :(得分:1)

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

oracle.com的更多信息。