在 JPA 2 w/Hibernate 中强制传递持久性顺序?

发布于 2024-12-04 03:12:19 字数 1504 浏览 3 评论 0原文

有没有办法强制 JPA 2 w/Hibernate 中对象的持久顺序?

假设我有三个类:ParentChildDeskParent 通过 @OneToMany 拥有 ChildDesk 的集合;一个孩子可以拥有一张桌子。此外,Parent 在两个集合上定义了传递持久性,但 Child 没有在其 Desk 上定义传递持久性:

class Parent {
    @OneToMany(cascade=CascadeType.ALL) Collection<Child> children;
    @OneToMany(cascade=CascadeType.ALL) Collection<Desk> desks;
    ...
}

class Child {
    @OneToOne(cascade={}) Desk desk;
    @ManyToOne Parent parent;
}

class Desk {
    @ManyToOne Parent parent;
}

理想情况下,我想创建同时拥有一个 Desk 和一个 Child 并持久化关系:

Parent parent = em.find(...);
Child child = new Child();
Desk desk = new Desk();
// add both desk and child to parent collections here
// set Parent attribute on both desk and child

如果我在事务中执行上述代码,Hibernate 会从 Parent 级联到其新的 Child 并尝试持久化新的子对象。不幸的是,这会导致“对象引用未保存的瞬态实例”错误,因为从 ParentDesk 的级联并未产生新的 Desk 对象尚未被持久化。

我知道我可以通过 EntityManagerlush() 操作 (em.flush()) 解决问题 - 创建 Child,创建 Desk ,将两者附加到 Parentem.flush(),然后将 Desk 附加到 Child,但我'我不太热衷于乱扔我的代码em.flush() 保存新持久对象的复杂图。是否有不同的方式向 JPA 2 或 Hibernate 发出信号,表明它应该始终首先保留新的 Desk 而不是新的 Child

Is there any way to force the persistence order of objects in JPA 2 w/Hibernate?

Say I have three classes: Parent, Child, and Desk. Parent owns collections of Child and Desk via @OneToMany; a Child can have one Desk. Furthermore, Parent defines transitive persistence on both collections, but Child does not define transitive persistence on its Desk:

class Parent {
    @OneToMany(cascade=CascadeType.ALL) Collection<Child> children;
    @OneToMany(cascade=CascadeType.ALL) Collection<Desk> desks;
    ...
}

class Child {
    @OneToOne(cascade={}) Desk desk;
    @ManyToOne Parent parent;
}

class Desk {
    @ManyToOne Parent parent;
}

Ideally, I'd like to create a Desk and a Child at the same time and persist the relationships:

Parent parent = em.find(...);
Child child = new Child();
Desk desk = new Desk();
// add both desk and child to parent collections here
// set Parent attribute on both desk and child

If I execute the above code in a transaction, Hibernate cascades from Parent to its new Child and attempts to persist the new Child object. Unfortunately, this results in an "object references an unsaved transient instance" error, because the cascade from Parent to Desk hasn't resulted in the new Desk object being persisted yet.

I know I can fix the problem with an EntityManager flush() operation (em.flush()) - create the Child, create the Desk, attach both to Parent, em.flush(), then attach the Desk to Child, but I'm not super-keen on littering my code with em.flush() to save complex graphs of new persistent objects. Is there a different way to signal to JPA 2 or Hibernate that it should always persist the new Desk first instead of the new Child?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

暗恋未遂 2024-12-11 03:12:20

看看你的描述,我认为持久化系统首先尝试按以下顺序持久化:

  • 首先是 Parent.children[i]
  • 每个 Children[i] 都有一个指向 Desk 的瞬态指针。系统无法持久化它,因为您没有将其配置为Cascade.Persist。

然后在持久化 Desk 时失败,并且您认为它在路径 Parent.desks[i] (配置为 Cascade)中失败,但也许失败不是来自该路径。

Looking at your description, I think that the Persistence system tries to persist first in this order:

  • First the Parent.children[i]
  • Each Children[i] has a transient pointer to Desk. The system fails to persist it because you have not configured it as Cascade.Persist.

Then it fails when persisting Desk, and you think that it fails in the path Parent.desks[i] (which is configured as Cascade) but maybe the fail doesn't come from this path.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文