0

这个问题可能是由于我对JPA可以做什么和不能做什么的无知,所以希望有人能够启发我。简而言之,从集合中删除实体不会传播到其祖父母的内存实例。以下是一个示例场景。

我们有三个实体(A、B、C)。

@Entity
public class C {

  @Id
  @GeneratedValue(strategy = GenerationType.IDENTITY)
  private int id;
  ...
  @ManyToOne(fetch = FetchType.EAGER, cascade = {CascadeType.PERSIST, CascadeType.MERGE})
  @JoinColumn(name="B_ID")
  private B b;
  ...
}

和,

@Entity
public class B {

  @Id
  @GeneratedValue(strategy = GenerationType.IDENTITY)
  private int id;
  private String name;

  @OneToMany(mappedBy = "b", fetch = FetchType.EAGER, cascade = {CascadeType.REMOVE, CascadeType.MERGE})
  private Set<C> cs;

  @ManyToOne(fetch = FetchType.EAGER, cascade = {CascadeType.PERSIST, CascadeType.MERGE})
  @JoinColumn(name = "A_ID")
  private A a;
  ...
}

和,

@Entity
public class A {
  @Id
  @GeneratedValue(strategy = GenerationType.IDENTITY)
  private int id;

  @OneToMany(mappedBy = "tenant", fetch = FetchType.EAGER, cascade ={CascadeType.PERSIST, CascadeType.MERGE, CascadeType.REMOVE})
  private Set<B> bs;
  ...
}

接下来,我们有一个用于修改 B 实例的无状态会话 bean。

@Stateless
public class BServiceBean implements BService {

  @PersistenceContext(unitName = Constants.PU)
  EntityManager em;

  @Override
  public B updateB(B b) {
    return em.merge(b);
  }

  @Override
  public B removeC(int bId, int cId) throws IllegalArgumentException {
    B b = em.find(B.class, bId);

    if (null == b) {
      throw new IllegalArgumentException("No b with id: " + bId + " exists.");
    }
    C c = em.find(C.class, cId);

    if (null == c) {
      throw new IllegalArgumentException("No c with id: " + cId + " exists.");
    }
    b.getCs().remove(c);
    em.remove(c);
    return em.merge(b);
  }
}

我们通过容器注入的 BService 实例在 servlet 中修改这些实体。

// created and persisted an A with three Bs, one of which has three Cs. 
A a = ...;
b2.setName(changedName);
b2 = bService.updateB(b2); // this change is reflected in a
...
b2 = bService.removeC(b2.getId(), c1.getId()); // this change is not reflected in a

// but it is in the db
a = aService.findAById(a.getId); // this instance of a has a b2 without a c1

为什么从 B 中的集合中删除实体不会在合并到 A 时级联,即使 B 中基本字段的更改确实会在 B 合并时级联到 A?我能做些什么来使 JPA 将实体删除向上级联到 A 吗?

4

1 回答 1

0

您只有级联持久化和合并您还应该需要级联删除。只需添加以下类型即可级联添加、更新和删除。

cascade =CascadeType.ALL
于 2013-07-03T09:44:04.140 回答