首页 文章

JPA和Hibernate - “坚持运营”

提问于
浏览
2

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

通过在其上调用persist方法或级联持久化操作,新实体实例变为托管和持久实例 . 应用于实体X的持久化操作的语义如下:...

是否可以在不显式调用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();

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

那么两个交易的#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实体是否会被保留?

1 回答

  • 1

    来自JPA specification,部分 3.2.4 (摘录):

    应用于实体X的刷新操作的语义如下:如果X是托管实体,则将其同步到数据库 . 对于来自X的关系引用的所有实体Y,如果与Y的关系已使用级联元素值cascade = PERSIST或cascade = ALL进行注释,则将持久化操作应用于Y

    所以,答案是肯定的, b 在所有示例中都是通过在刷新时从 a 级联 PERSIST 操作来保留的 .

相关问题