我正在尝试建立一个用户和一个联系人管理项目。
我有很多课程,因此将其限制在这里所关注的范围内。我有一个userAccount,userProfile和组
这是UserAccount映射

@Id @GeneratedValue
@Column(name="USER_ACCOUNT_ID")
private Long ID;
 ......
 @Column(name="EMAIL", length=100, unique=true)
private String email;

@OneToOne(targetEntity=UserProfileImpl.class,cascade={CascadeType.ALL})
 @org.hibernate.annotations.Cascade(value=org.hibernate.annotations.CascadeType.DELETE_ORPHAN)
@JoinColumn(name="USER_PROFILE_ID")
private UserProfile profile;

 @OneToMany(targetEntity=GroupImpl.class, cascade={CascadeType.ALL})
 //    @JoinColumn(name="USER_ACCOUNT_ID")
@JoinTable(name = "USER_ACCOUNT_CONTACT_GROUP", joinColumns = @JoinColumn(name = "USER_ACCOUNT_ID"), inverseJoinColumns = @JoinColumn(name = "GROUP_ID"))
@org.hibernate.annotations.Cascade(value=org.hibernate.annotations.CascadeType.DELETE_ORPHAN)
private Set<Group> groups = new HashSet<Group>();
........


这是userProfile

@Id @GeneratedValue(strategy=GenerationType.IDENTITY)
@Column(name="USER_PROFILE_ID")
private Long ID;
.....
 @OneToOne(mappedBy="profile", targetEntity=UserAccountImpl.class)
private UserAccount userAccount;
.....


这是小组

@Id @GeneratedValue(strategy=GenerationType.IDENTITY)
@Column(name="GROUP_ID")
private Long ID;
.......
@Column(name="NAME", length=100, unique=true)
private String Name;

@ManyToOne(targetEntity=UserAccountImpl.class)
@JoinColumn(name="USER_ACCOUNT_ID",nullable=false)
private UserAccount userAccount;


基本上,一切都很好。在进行双向关联之前,在将userAccount对象添加到group.so之前进行了双向关联。我创建了userProfile,userAccount和group(使用spring @autowired)。
在setUP(@Before)方法上,我为userProfile设置了一些道具,并将其连同其道具一起添加到useAccount,并将其保留,然后将useAccount设置为该组。
在tearDown(@After)上,我删除了userACcount。
在我的testSave(保存组)上运行良好(对所有操作使用相同的会话),但是在控制台上没有用于组的delete sql查询,但是虽然删除了userAccount。
通过删除拆解方法中的userAccount,我希望将组删除到,但是事实并非如此。
更糟糕的是,由于组名的唯一性限制,其他测试都失败了。我在网上搜索,但是我尝试的所有方法似乎都无法正常工作。谁能救我:)?我的意思是我应该怎么做?谢谢阅读

这是我根据收到的回复尝试过的更新。
我已经将此添加到group.setUserAccount(null)到我的removeGroup中,现在是

public void removeGroup(Group group) {
    try{
       if(this.groups.contains(group)){
        group.setUserAccount(null);
        this.groups.remove(group);
       }
    } catch(Exception ex){
        ex.printStackTrace();
    }
}


所以对于我使用的具有相同行为的测试,即删除userAccount但不删除组

ua1.removeGroup(g1);
uaDao.delete(ua1);


我猜它没有进入if块,因为我应该具有与此相同的行为:

 g1.setUserAccount(null);
 uaDao.delete(ua1);


另一个抛出错误


  PropertyValueException:非null属性引用null或瞬态值


所以我想我将使用删除该组:

gDao.delete(g1);
uaDao.delete(ua1);


希望我能找到解决的办法。感谢那些帮助过我的人,尤其是Pascal,如果您有其他想法或发现我的代码有问题,我将很高兴更正它。感谢阅读

最佳答案

首先,如果UserAccount-> Group关系是双向的,则需要将逆集合侧映射为

@OneToMany(targetEntity=GroupImpl.class, cascade{CascadeType.ALL},mappedBy="userAccount")


因此,现在Hibernate知道UserAccount是该集合的所有者。现在按照@Pascal的指示进行删除,您需要解除绑定。由于Hibernate忽略了集合,因此所有者负责绑定关系,因此基本上像这样的帮助器方法会在UserAccount中创建关联

public void addGroup(Group group){
     group.setUserAccount(this);
     groups.add(group);
}


现在用于删除另一个辅助方法

public void removeGroup(Group group){
    group.setUserAccount(null);
    groups.remove(group);
}


现在要移除

UserAccount ua = //load user account object
for(Group g : ua.getGroups())
      ua.removeGroup(g);

session.delete(ua);


您的代码现在应该可以工作了。您不必按照我的方式进行操作,但希望您能如愿以偿。DELETE_ORPHAN应该照顾您对groups的级联删除

10-04 23:24