【问题标题】:JPA and Hibernate - "persist operation"JPA 和 Hibernate - “持久化操作”
【发布时间】:2017-04-17 13:22:17
【问题描述】:

我正在阅读 JPA 2.1 规范并且有这个片段:

一个新的实体实例成为托管和持久的通过调用 其上的persist方法或级联persist操作。这 应用于实体 X 的持久操作的语义为 如下:...

是否可以在不显式调用persist() 方法的情况下调用persist 操作,或者persist 操作总是必须通过调用persist() 来触发?

假设我有两个实体 A 和 B,其中 A 与 B 有 OneToMany(cascade=PERSIST) 关系。

tx.begin();
A a = new A();
B b = new B();
a.getBCollection().add(b);
entityManager.persist(a);
tx.commit();

同:

tx.begin();
A a = new A();
entityManager.persist(a);
B b = new B();
a.getBCollection().add(b);
tx.commit();

在第二个例子中,B实体是否会被持久化(持久化操作将被级联),即使实体是在调用persist()方法后添加的?或者我必须在调用 persist() 方法之前将 B 实体添加到集合中,就像在第一个示例中那样,只有这样,persist 操作才会被级联?

那么#3 的例子有两个交易:

tx1.begin();
A a = new A();
entityManager.persist(a); //persist with key 1L
tx1.commit();

tx2.begin()
B b = new B();
A a = entityManager.find(A.class, 1L);
a.getBCollection().add(b);
tx2.commit();

第二个事务没有调用persist()方法,但是A处于托管状态,那么B实体会被持久化吗?

【问题讨论】:

    标签: hibernate jpa


    【解决方案1】:

    来自JPA specification3.2.4部分(摘录):

    应用于实体 X 的刷新操作的语义如下 如下:

    • 如果 X 是托管实体,它会同步到数据库。
      • 对于由来自 X 的关系引用的所有实体 Y,如果与 Y 的关系已使用级联元素值进行注释 cascade=PERSIST 或 cascade=ALL,持久化操作应用于 Y

    所以,答案是肯定的,b 在刷新时通过将PERSIST 操作从a 级联到它,在所有示例中都保持不变。

    【讨论】:

    • 所以 CascadeType.PERSIST 不直接连接到 persist() 方法,MERGE 到 merge() 等?我一直这么认为
    猜你喜欢
    • 2013-11-12
    • 1970-01-01
    • 2017-04-09
    • 2011-04-02
    • 1970-01-01
    • 2015-05-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多