我有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?或者我应该重新考虑我的级联战略?
答案 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);
我不确定这是否应该用更好的级联策略或非常合法的实践来替代。