Hibernate:多对多与属性的关系:使用Annotations进行正确配置

时间:2011-12-20 13:12:10

标签: java hibernate annotations cascade

我遇到了Hibernate的问题(感谢 Thomas 现在问题更清晰了。)

简而言之:

当关系具有属性并且我们需要级联保存,删除和更新时,如何使用Hibernate配置ManyToMany关联?

In Large:

想象一下以下数据库:

             User     Profile
                M______N
                     |
                     attribute

这里有3个表:

"User", "Profile" and "User_Profile".

现在假设User_Profile有一个关系属性(显然是关键字)。

好的,现在通过以下方式转换为Hibernate:

 User:
 // The relation is Many to Many, but considering that it has an attribute, this is OneToMany with the ManyMany RelationShip
 @OneToMany(mappedBy="user", targetEntity=UserProfile.class)    
 @Cascade({CascadeType.SAVE_UPDATE, CascadeType.DELETE})
 @LazyCollection(LazyCollectionOption.TRUE)
 private Set<UserProfile> userProfile = new HashSet<UserProfile>();


 UserProfile:
 @Id    
 @ManyToOne(targetEntity=User.class,fetch=FetchType.LAZY)   
 @Cascade({CascadeType.LOCK})   
 @JoinColumns({ @JoinColumn(name="...", referencedColumnName="...") })  
 private User user; 

 @Id    
 @ManyToOne(targetEntity=Profile.class,fetch=FetchType.LAZY)    
 @Cascade({CascadeType.LOCK})   
 @JoinColumns({ @JoinColumn(name="...", referencedColumnName="...") })  
 private Profile profile;

所以,我认为配置是正确的,并且保存,如果用户具有Profile子节点,则独立保存所有这些。问题是当我尝试更新用户时:

 getHibernateTemplate().getSessionFactory().getCurrentSession().clear();
 getHibernateTemplate().saveOrUpdate( user );
 getHibernateTemplate().getSessionFactory().getCurrentSession().flush();

如果有一组空的个人资料,Hibernate不会删除个人资料关系。只添加配置文件(覆盖旧配置文件)......这很罕见......问题出在哪里?

提前谢谢

1 个答案:

答案 0 :(得分:0)

你实际做的只是删除关系,因此没有DELETE级联,这就是为什么没有被删除的原因。

尝试添加Hibernate级联类型DELETE_ORPHAN(使用@Cascade注释)以使Hibernate删除不再引用的实体。

此外,我不会单独删除Mini个实体。如果没有关系,即Mini s的集合为空,那么保持现在代表空集合的SuperMini实体通常是没有意义的(在极少数情况下它可能有意义,只是想要你思考你是否需要它们。)

编辑

请注意,对于DELETE_ORPHAN,您应该重复使用该集合,否则可能会删除并重新插入所有关系。

基本上,Hibernate会看到该组被更改,并将为“旧”集发出删除,并为“新”集发出重新插入。这可能是需要的,但如果您只想要更新,即只删除不在集合中的实体,您应该执行以下操作:

  1. 清除集合
  2. 使用addAll(...)
  3. 将“new”集添加到重用且已清除的集合中

    这应该仅触发更新(和删除孤儿)。