无法删除映射的对象,Hibernate JPA

时间:2015-07-16 14:31:07

标签: hibernate jpa

我有3个实体,Party将oneToMany映射到Invitation,它与Guest映射为manyToOne。 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();

在导出的数据库中,所有外键都设置为on update cascade, on delete cascade

我的问题:

在自定义更新方法中,我尝试删除来自派对的邀请。 通过从party.invitations中删除Invitation个对象并提交party,我发现已移除的Invitations仍在那里。

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);

我收到PersistentException:

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] 

我做错了什么?我是否应该担心我的更新方法的代码中存在的关联,例如我用来迭代邀请的临时HashMaps?或者我应该重新考虑我的级联战略?

2 个答案:

答案 0 :(得分:0)

您正面临一个来自JPA 1.0的众所周知的问题(并且它将保留在JPA的未来版本中以保持兼容性。)

JPA 2.0为此缺陷提供了一种解决方法:您可以将属性orphanRemoval=true添加到oneToMany定义,以便在从集合中删除子实体时显式请求删除子实体:

@OneToMany(orphanRemoval=true, mappedBy="party", targetEntity=com.acme.party.model.Invitation.class)
...
private java.util.Set invitation = new java.util.HashSet();

答案 1 :(得分:0)

我已成功删除邀请,方法是将其从guest.getInvitation()映射中删除。看起来这是保持invitation持续存在的关联。

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);

我不确定这是否应该用更好的级联策略或非常合法的实践来替代。