为什么 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.DETACHFetchType.LAZY 屏蔽了?当我将获取类型更改为 EAGER 时,分离会传播到 B 的详细信息集合。

我使用 Eclipse Link 作为引擎。

--编辑问题是 CascadeType.DETACH 没有在详细集合中传播。在分离之前管理和获取所有实体。

Detach 仅级联获取的属性和关系,并且您在分离 A 之后获取 B 的列表。仅获取 B returns 提供者的集合实现 - 实际集合的代理,并且不获取 B结果。只有访问此集合(例如对其调用 size)才会触发提取。

在其他提供程序上,这会导致异常,但只要上下文仍然可用,EclipseLink 就允许获取惰性关系。如果实体未序列化且 EMF 仍处于打开状态,为了保持对象身份,EclipseLink 将使用从中读取实体的 EntityManager 来获取您的集合,从而在该 EntityManager 中管理结果。