我发现,使用原始类型为对象@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作品也。
因此,它是推荐的做法总是使用对象包装的基本数据类型(如龙,而不是长),而不是基本类型。 描述这是推荐的做法任何第三方资源将是非常好的。