始终使用JPA @Id,而不是原始类型原始对象包装?(Always use primitive ob

2019-06-25 23:12发布

我发现,使用原始类型为对象@Id为JPA结合春季数据JPA的问题。 我对父母侧Cascade.ALL父/子关系,和孩子有PK这同时也是父母的FK。

class Parent {
    @Id
    private long id;

    @OneToOne(mappedBy = "parent", cascade = ALL)
    private Child child;
}

class Child {
    @Id
    @OneToOne
    private Parent parent;
}

所以,当我运行:

...
Parent parent = new Parent();
Child child  = new Child(parent);
parent.setChild(child);  
em.persist(parent)
...

一切工作正常。 但我用春天JPA的数据持久化的实体,所以我跑,而不是:

parentRepository.save(parent); // instead of em.persist(parent);

而这一次是失败,出现以下异常:

Caused by: org.hibernate.TransientObjectException: object references an unsaved transient instance - save the transient instance before flushing: Parent

问题是,春天JPA的数据保存()方法检查的实体是否是新的,如果它是新的,然后em.persist()用于否则使用em.merge()。

这里的有趣的部分是如何春季检查是否该实体是新的或不:

getId(entity) == null;

而且,当然,这是假的,因为我曾经长期作为@Id类型的,更长久的默认值是0。当我改变长隆一切与Spring数据JPA作品也。

因此,它是推荐的做法总是使用对象包装的基本数据类型(如龙,而不是长),而不是基本类型。 描述这是推荐的做法任何第三方资源将是非常好的。

Answer 1:

我想说的是,建议使用对象类型,而不是因为你看到的情况的图元。 没有区别,如果该实体是新的或预先存在与原始标识符的方式。 我已经使用休眠多年,我一直使用对象标识符。



Answer 2:

我会用一个对象类型。 在XML映射,你可以把一个“未保存值”属性,但我不认为这是一个直接的翻译注释本。 其结果是,它的安全坚持与对象类型。

和大多数程序员会期望在一个标识符的“空”值是指未保存的反正。



文章来源: Always use primitive object wrappers for JPA @Id instead of primitive type?