一对多关系JPA / Hibernate删除链接 [英] One to Many relationship JPA/Hibernate removing links
问题描述
class Child {
@ManyToOne
@JoinTable (name =CHILDREN_WITH_PARENT,
joinColumns = {@JoinColumn(name =CHILD_ID)},
inverseJoinColumns = {@JoinColumn(name =PARENT_ID)}
)
私人父母;
}
类父母{
@OneToMany(mappedBy =parent,cascade = CascadeType.ALL)
Set< Child> childrens = new HashSet< Child>();
public void persistOrMerge(){
EntityManager em = entityManager();
em.getTransaction()。begin();
尝试{
if(em.contains(this))
return;
if(id == null || id == 0){
this.setCreatedDate(new Date());
em.persist(this);
} else {
Parent prev = em.find(Parent.class,this.id);
if(prev == null){
em.persist(this);
} else {
this.setCreatedDate(new Date());
em.merge(this);
}
}
em.flush();
em.getTransaction()。commit();
} finally {
em.close();
code
$ b < (GWT + EntityProxy) Set< ChildProxy> children = new HashSet< ChildProxy>();
if(childIsNew)
child = request.create(Children.class)
else
child = request.edit(oldChild)
children.add(child);
//如果子项被删除,它们不包含在set
中//我们将发送回服务器
parent.setChildren(children)
parent.persistOrMerge();
此代码仅适用于添加新的子项。即使父母课程收到一个空的儿童套装,从父母中移除孩子也不起作用。
您可以告诉我在哪里丢失了什么?
感谢!
解决方案我会先说这是一个非常糟糕的主意,实体是使用实体的实体直接经理。
EntityManager.merge()方法返回实际的合并实例,这意味着在您的代码中,当您发出
em.merge(this)
您没有保证合并的实例不再与this相对应,从这一点开始,您可能会看到各种逻辑问题。
如果你不认为这是这样的一个重大的问题,你应该通过打开关系的OneToMany一边的孤儿删除来解决你的问题,前提是这些孩子没有被用在其他关系中的任何其他地方。
@OneToMany(mappedBy =parent,cascade = CascadeType.ALL,orphanRemoval = true)
Set< Child> childrens = new HashSet< Child>();
JPA 2.0规范声明:
指定为OneToOne或OneToMany的关联支持使用orphanRemoval I have bidirectional relationship setup as follows: On my client side I have following code (GWT + EntityProxy) This code only works for adding new children. Removing of children from parent does not work even if parent class receives an empty children set. The linkages in JOIN table are not removed. Can you please tell where I am missing something? Thanks! I will start by saying that is a really bad idea that the entity is the one using the entity manager directly. The EntityManager.merge() method returns the actual merged instance, this implies that in your code, when you issue You have no guarantee whatsoever that the merged instance corresponds to "this" anymore, and from that point on you may see all kinds of logical problems. If you do not think this is such a big deal, your problem should be solved by turning on orphan removal on the OneToMany side of the relationship, provided that the children are not being used anywhere else in other relationships. Otherwise you will have to do the merging manually. The JPA 2.0 specification states that Associations that are specified as OneToOne or OneToMany support use of the orphanRemoval
option. The following behaviors apply when orphanRemoval is in effect: 这篇关于一对多关系JPA / Hibernate删除链接的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!
选项。当orphanRemoval生效时,以下行为适用:
的目标,
关系(通过将
关系设置为null或从关系
集合中除去
实体),删除操作
将应用于实体
孤儿。删除操作是在冲洗
操作时应用的
。 orphanRemoval
功能适用于由其父实体私有拥有
的
实体。便携式
应用程序必须否则不能
取决于特定的
删除顺序,并且不得重新分配
实体,该实体已被孤立为
另一种关系或
试图坚持它。如果被孤立的实体
是已分离的,新的或
被删除的实体,则
orphanRemoval的语义不适用。
a托管来源实体,则删除
操作将按照
与第3.2.3节的规则(和
)级联至
关系目标因此没有必要为
关系指定
cascade = REMOVE)[20]。
class Child{
@ManyToOne
@JoinTable(name = "CHILDREN_WITH_PARENT",
joinColumns = {@JoinColumn(name = "CHILD_ID")},
inverseJoinColumns = {@JoinColumn(name = "PARENT_ID")}
)
private Parent parent;
}
class Parent{
@OneToMany(mappedBy="parent", cascade=CascadeType.ALL)
Set<Child> childrens = new HashSet<Child>();
public void persistOrMerge() {
EntityManager em = entityManager();
em.getTransaction().begin();
try {
if (em.contains(this))
return;
if (id == null || id == 0) {
this.setCreatedDate(new Date());
em.persist(this);
} else {
Parent prev = em.find(Parent.class, this.id);
if (prev == null) {
em.persist(this);
} else{
this.setCreatedDate(new Date());
em.merge(this);
}
}
em.flush();
em.getTransaction().commit();
} finally {
em.close();
}
}
}
Set<ChildProxy> children = new HashSet<ChildProxy>();
if(childIsNew)
child = request.create(Children.class)
else
child = request.edit(oldChild)
children.add(child);
//If children are deleted, they are not contained in the set
//we are sending back to server
parent.setChildren(children)
parent.persistOrMerge();
em.merge(this)
@OneToMany(mappedBy="parent", cascade=CascadeType.ALL, orphanRemoval=true)
Set<Child> childrens = new HashSet<Child>();