Hibernate 无法删除映射对象,请休眠JPA
我有3个实体,Hibernate 无法删除映射对象,请休眠JPA,hibernate,jpa,Hibernate,Jpa,我有3个实体,Party映射为一个omany withInvitation,映射为多个omany withGuest。JPA的定义如下: 派对课 @OneToMany(mappedBy="party", targetEntity=com.acme.party.model.Invitation.class) @org.hibernate.annotations.Cascade({org.hibernate.annotations.CascadeType.SAVE_UPDATE, org.hiber
Party
映射为一个omany withInvitation
,映射为多个omany withGuest
。JPA的定义如下:
派对课
@OneToMany(mappedBy="party", targetEntity=com.acme.party.model.Invitation.class)
@org.hibernate.annotations.Cascade({org.hibernate.annotations.CascadeType.SAVE_UPDATE, org.hibernate.annotations.CascadeType.LOCK})
@org.hibernate.annotations.LazyCollection(org.hibernate.annotations.LazyCollectionOption.FALSE)
private java.util.Set invitation = new java.util.HashSet();
邀请课程
@ManyToOne(targetEntity=com.acme.party.model.Party.class)
@org.hibernate.annotations.Cascade({org.hibernate.annotations.CascadeType.LOCK})
@JoinColumns({ @JoinColumn(name="partyId", referencedColumnName="partyId", nullable=false) })
private com.acme.party.model.Party party;
@ManyToOne(targetEntity=com.acme.party.model.Guest.class)
@org.hibernate.annotations.Cascade({org.hibernate.annotations.CascadeType.LOCK})
@JoinColumns({ @JoinColumn(name="guestId", referencedColumnName="guestId", nullable=false) })
private com.acme.party.model.Guest guest;
@OneToMany(mappedBy="guest", targetEntity=com.acme.party.model.Invitation.class)
@org.hibernate.annotations.Cascade({org.hibernate.annotations.CascadeType.SAVE_UPDATE, org.hibernate.annotations.CascadeType.LOCK})
@org.hibernate.annotations.LazyCollection(org.hibernate.annotations.LazyCollectionOption.FALSE)
private java.util.Set invitation = new java.util.HashSet();
客席
@ManyToOne(targetEntity=com.acme.party.model.Party.class)
@org.hibernate.annotations.Cascade({org.hibernate.annotations.CascadeType.LOCK})
@JoinColumns({ @JoinColumn(name="partyId", referencedColumnName="partyId", nullable=false) })
private com.acme.party.model.Party party;
@ManyToOne(targetEntity=com.acme.party.model.Guest.class)
@org.hibernate.annotations.Cascade({org.hibernate.annotations.CascadeType.LOCK})
@JoinColumns({ @JoinColumn(name="guestId", referencedColumnName="guestId", nullable=false) })
private com.acme.party.model.Guest guest;
@OneToMany(mappedBy="guest", targetEntity=com.acme.party.model.Invitation.class)
@org.hibernate.annotations.Cascade({org.hibernate.annotations.CascadeType.SAVE_UPDATE, org.hibernate.annotations.CascadeType.LOCK})
@org.hibernate.annotations.LazyCollection(org.hibernate.annotations.LazyCollectionOption.FALSE)
private java.util.Set invitation = new java.util.HashSet();
在导出的数据库中,所有外键在更新级联时设置为,在删除级联时设置为
我的问题:
在自定义更新方法中,我正在尝试从聚会中删除邀请。
通过从party.investments中删除investment
对象并提交party
,我注意到删除的邀请函仍然存在
party.getInvitation().remove(invitation12);
party.getInvitation().remove(invitation23);
session.saveOrUpdate(party);
通过另外删除邀请
party.getInvitation().remove(invitation12);
party.getInvitation().remove(invitation23);
session.delete(invitation12);
session.delete(invitation23);
session.saveOrUpdate(party);
我得到了一个持续的例外:
org.orm.PersistentException: org.hibernate.ObjectDeletedException: deleted object would be re-saved by cascade (remove deleted object from associations): [com.acme.party.model.Invitation#923]
我做错了什么?我是否应该担心更新方法的代码中存在的关联,例如,我用来迭代邀请的临时哈希映射?还是应该重新考虑我的级联策略 您正面临来自JPA1.0的一个众所周知的问题(为了保持兼容性,它将保留在JPA的未来版本中)
JPA 2.0为此缺陷提供了一种解决方法:您可以将属性orphanRemoving=true
添加到oneToMany定义中,以便在从集合中删除子实体时明确请求删除它们:
@OneToMany(orphanRemoval=true, mappedBy="party", targetEntity=com.acme.party.model.Invitation.class)
...
private java.util.Set invitation = new java.util.HashSet();
我已经设法删除了邀请,方法是将它们从guest.getInvitation()
映射中删除。看起来这是保留邀请的关联
party.getInvitation().remove(invitation12);
party.getInvitation().remove(invitation23);
guest1.getInvitation().remove(invitation12);
guest2.getInvitation().remove(invitation23);
session.delete(invitation12);
session.delete(invitation23);
session.saveOrUpdate(party);
我不确定这是一种应该用更好的级联策略来取代的冗余,还是一种相当合法的做法 1)您如何获得invitation12
和invitation23
实例?2) 调用party.getInvitation().remove(invitation12)之后
,invitation12
是否仍在聚会中。getInvitation()
设置?@DraganBozanovic 1)我正在从聚会中获取它们。getInvitation()
,尽管我重复了几次,并与另一个收藏进行交叉检查。2) 是的,我确信在我打电话给session.saveOrUpdate(party)
之前,party.getInvitation()
没有包含它们。你能发布邀请的hashCode
和equals
吗?@DraganBozanovic我认为这不相关,但她说:我没有覆盖equals
。它正在使用对象。equals
。没有hashCode,但我得到的印象是,孤儿删除
主要是为了与较旧的JPa兼容,但是您可以(而且可能应该)避免在JPa中使用它,不幸的是,没有。问题是,JPA-1.0模型在与JPA-2提供程序一起运行时,不应该突然表现出不同的行为。我尝试使用删除
,但guest.getInvitation()
中的关联仍在阻止删除。这就是为什么我仍然怀疑我的级联策略是否正确。