【发布时间】:2018-04-22 06:13:19
【问题描述】:
在带有JPA 的标准JEE 应用程序中,我有一个主实体A,其中包含B 的一对多集合。A 实体具有以下形式:
@Table(name = "TABLE_A")
@Entity
public class A implements Serializable {
@Id
@SequenceGenerator(name = "A_ID_GENERATOR", sequenceName = "SEQ_A", allocationSize = 1, initialValue = 1)
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "A_ID_GENERATOR")
@Column(unique = true, nullable = false, precision = 16)
private Long id;
@OneToMany(cascade = CascadeType.ALL , fetch = FetchType.LAZY , mappedBy = "a")
private List<B> bCollection;
public List<B> getB() {
return this.bCollection;
}
public void setB(List<B> bCollection) {
this.bCollection = bCollection;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
}
实体 B 具有以下形式:
@Table(name = "TABLE_B")
@Entity
public class B implements Serializable {
@Id
@SequenceGenerator(name = "B_ID_GENERATOR", sequenceName = "SEQ_B", allocationSize = 1, initialValue = 1)
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "B_ID_GENERATOR")
@Column(unique = true, nullable = false, precision = 16)
private Long id;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "A_FK")
private A a;
public Long getId() {
return this.id;
}
public void setId(Long id) {
this.id = id;
}
public A getA() {
return this.a;
}
public void setA(A a) {
this.a = a;
}
}
在 @TransactionAttribute(TransactionAttributeType.REQUIRED) 的 EJB 方法中,我从 DB 中检索 A 并调用 getB() 以获取当前 A 下 B 的数据。然后我手动分离当前 A:
em.detach(a);
在 EJB 方法返回之前,如果我使用 em.contains(b) 测试当前 A 下的 B 实例,即使我使用 CascadeType.ALL,它们仍然受到管理。
EJB 中的事务方法如下所示:
@TransactionAttribute(TransactionAttributeType.REQUIRED)
public void doSomething(String aBusinessKey) {
A a = fetchAByItsBusinessKey(aBusinessKey);
List<B> bs = a.getB();
em.detach(a);
//Test if Bs are managed
boolean isManaged = em.contains(bs.get(0));
}
谁能解释为什么CascadeType.DETACH 被FetchType.LAZY 屏蔽?当我将 Fetch Type 更改为 EAGER 时,分离会传播到 B 的详细信息集合。
作为引擎,我使用Eclipse Link。
--EDIT 问题是 CascadeType.DETACH 没有在详细集合中传播。所有实体都在分离之前进行管理和获取。
【问题讨论】:
-
好吧,我可能错了:你的意思是这部分并调用getB()的意思是所有实体在分离之前都被获取和管理?
-
是的,在同一个事务中,我获取一个主实体 A,我调用 getB() 来获取它的 B 类型的详细实体,然后我调用 em.detach(a),我希望实体管理器由于 CascadeType.ALL 而分离 B 实体
-
你能把你正在使用的
B也放进去吗?有没有,如果,那么A有什么样的注释?我想测试一下。 -
检查你的第一个代码sn-p:它有注释
@OneToOne。然后它有private B b;,但也有List<B> getB(),它返回b?你说 A 包含 B 的一对多集合?因此,您需要在代码中编辑一些内容以使其更易于理解。就像把这些实体像你一样测试它们。 -
@pirho 我编辑了代码以提供 A 和 B 实体并更正拼写错误。
标签: jpa jakarta-ee eclipselink jpa-2.0