JPA实体ID - 原始类型还是对象类型(long或Long)

45

你的实体ID应该使用long(原始类型)还是Long(对象类型)?

  • ID是我的表的主键,在数据库中从不为“null”。
  • 我的同事建议使用对象类型Long。
  • Hibernate反向工程工具默认为id生成原始类型long。

选择什么?long还是Long?

@Entity
@Table(name = "COUNTRY")
public class CountryEntity implements java.io.Serializable {
    private static final long serialVersionUID = 1L;

    @Id
    @Column(name = "ID")
    private long id;
    @Column(name = "NAME")
    private String name;
    @Column(name = "CURRENCY")
    private String currency;
    @Column(name = "PEOPLE")
    private Long people;
    @Column(name = "SIZE")
    private Long size;

    public CountryEntity() {
    }
3个回答

43

我认为使用Long类型更好,因为检查实体是否具有持久性标识时,检查null值更加正确(在MySQL中,您可以具有值为0的ID)。此外,一些库(例如Spring)默认情况下在其逻辑中使用Long类型的ID。请参阅此实现以获取示例。

原始类型的小优点是:它占用的空间稍微少一些。

PS:根据JPA规范,两者都是正确的且受支持的,本问题的答案在某种程度上是基于个人意见的。


11

我更倾向于使用 Long 类型,因为如果让数据库生成实体的 ID(这是应该的),那么您可以通过检查 id==null 来确定最近创建的 CountryEntity 对象是否已经持久化。如果使用 long 类型,则 id 始终具有非空值(最初为 0),并且在持久化实体时会发生更改。


1
"你能否提供这个推论的参考依据?我有些赞同,但更希望有一个来源支持这种观点。" - coderatchet
如果我这样写 Long id = -1L 会怎么样? - silentsudo
为什么要这样做呢?你不能将id设置为常量,因为作为主键它必须是唯一且非空的。虽然在技术上可以使用-1作为“尚未持久化”的值,但如果某个实体确实具有id=-1,那该怎么办呢?在那些被迫使用long而不是Long的情况下,您可以使用-1作为支撑,然后确保-1作为真正的键永远不会发生。但是,您必须非常绝望才能这样做。 - wallenborn
如果月球撞向地球了怎么办?我们该如何生存?是的,我很认真。 “让它失败”实际上是一种纪律。我们应该关注保持良好的实践和良好的设计,避免使用可为空的包装类型肯定是其中之一。此外,我们应该使用编程语言的语义编写对象。这就是为什么我们首先使用JPA提供程序的原因。我的目标是基于随机(且可以说是愚蠢的)持久性提供程序可能如何使用它们而不是修改我的对象。 - Martin Andersson

1

使用字符串类型作为实体ID。数字类型适用于序列或执行数学比较和计算。如果使用GUID / UUID生成器进行ID生成,则通常需要允许非数字字符(例如连字符)。


4
在大多数(或全部?)数据库引擎中,字符串作为主键比整数或其他数字要低效得多。这在与其他表进行连接时最频繁地发生作用。任何曾经与MySQL字符集和排序挑战斗争过的人都会告诉你,这是在找麻烦。整数或长整数就是它们本来的样子(但永远不是浮点数)。使用字符串、GUID或二进制值存在有效理由,但它们并不是普遍情况。 - goosemanjack
1
@goosemanjack,这个问题/答案是关于在Java持久化实体中表示Id时选择哪种数据类型,而不是底层数据库列可能是BIGINT类型的问题。 - i3ensays

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接