在JEE
的标准JPA
应用程序中,我有一个包含一对多B集合的主实体A.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
。
- 编辑问题是CascadeType.DETACH不会在详细信息集合中传播。在分离之前管理和获取所有实体。
答案 0 :(得分:1)
仅分离获取的属性和关系的级联,并且在分离A之后获取B列表.getB仅返回提供者的集合实现 - 实际集合的代理,并且不获取结果。只有访问此集合(例如调用它的大小)才会触发获取。
在其他提供程序上,这会导致异常,但只要上下文仍然可用,EclipseLink就允许获取延迟关系。如果实体未被序列化并且EMF仍处于打开状态,为了保持对象标识,EclipseLink将使用读取实体的EntityManager来获取您的集合,从而导致在该EntityManager中管理结果。