这个问题可能是因为我不知道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;
...
}
接下来,我们有一个无状态会话bean,用于修改B的实例。
@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?
发布于 2013-07-03 09:44:04
你只需要级联,持久化和合并,你也应该需要级联删除。只需添加以下类型即可级联添加、更新和删除。
cascade =CascadeType.ALL
https://stackoverflow.com/questions/17444561
复制相似问题