为什么 CascadeType.DETACH 在 Eclipselink 中 FetchType.LAZY 的 OneToMany 关系中不起作用?
Why CascadeType.DETACH is not working in OneToMany relationships of FetchType.LAZY in Eclipselink?
在具有 JPA
的标准 JEE
应用程序中,我有一个包含 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方法的return之前,如果我用em.contains(b)
测试当前A下的B实例,即使我使用CascadeType.ALL
.[=25=,它们仍然被管理]
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
屏蔽了?当我将获取类型更改为 EAGER
时,分离会传播到 B 的详细信息集合。
我使用 Eclipse Link
作为引擎。
--编辑问题是 CascadeType.DETACH 没有在详细集合中传播。在分离之前管理和获取所有实体。
Detach 仅级联获取的属性和关系,并且您在分离 A 之后获取 B 的列表。仅获取 B returns 提供者的集合实现 - 实际集合的代理,并且不获取 B结果。只有访问此集合(例如对其调用 size)才会触发提取。
在其他提供程序上,这会导致异常,但只要上下文仍然可用,EclipseLink 就允许获取惰性关系。如果实体未序列化且 EMF 仍处于打开状态,为了保持对象身份,EclipseLink 将使用从中读取实体的 EntityManager 来获取您的集合,从而在该 EntityManager 中管理结果。
在具有 JPA
的标准 JEE
应用程序中,我有一个包含 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 的数据。然后我使用 :
em.detach(a);
在EJB方法的return之前,如果我用em.contains(b)
测试当前A下的B实例,即使我使用CascadeType.ALL
.[=25=,它们仍然被管理]
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
屏蔽了?当我将获取类型更改为 EAGER
时,分离会传播到 B 的详细信息集合。
我使用 Eclipse Link
作为引擎。
--编辑问题是 CascadeType.DETACH 没有在详细集合中传播。在分离之前管理和获取所有实体。
Detach 仅级联获取的属性和关系,并且您在分离 A 之后获取 B 的列表。仅获取 B returns 提供者的集合实现 - 实际集合的代理,并且不获取 B结果。只有访问此集合(例如对其调用 size)才会触发提取。
在其他提供程序上,这会导致异常,但只要上下文仍然可用,EclipseLink 就允许获取惰性关系。如果实体未序列化且 EMF 仍处于打开状态,为了保持对象身份,EclipseLink 将使用从中读取实体的 EntityManager 来获取您的集合,从而在该 EntityManager 中管理结果。