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

发布于 2024-12-21 21:18:09 字数 1693 浏览 0 评论 0原文

我在使用 Hibernate 时遇到了问题(感谢 Thomas,现在问题更加清晰了)。

简而言之:

当关系具有属性并且我们需要级联保存、删除和更新时,如何配置与 Hibernate 的多对多关联?

大图:

想象一下以下数据库:

             User     Profile
                M______N
                     |
                     attribute

这里有 3 个表:

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

现在假设 User_Profile 有 1 个关系属性(显然还有键)。

好的,现在这将通过以下方式转换为 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;

因此,我认为配置是正确的,并且如果用户有配置文件子级保存所有配置文件,则独立保存。问题是当我尝试更新用户时:

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

如果存在一组空的配置文件子项,Hibernate 不会删除配置文件关系。仅添加配置文件(覆盖旧的)...这很少见...有什么问题?

先感谢您

I have a problem with Hibernate (Thanks to Thomas now the problem is more legible).

In Short:

How to configure a ManyToMany association with Hibernate when the relationship has an attribute and we need save, delete and update in cascade?

In Large:

Imagine the following DataBase:

             User     Profile
                M______N
                     |
                     attribute

There are 3 tables here:

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

Now imagine User_Profile has 1 attribute for the relation (and obviously the keys).

Ok, now this is translating to Hibernate by the following:

 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;

So, I think the configuration is correct, and the save, independently if the User has Profile childrens save all of them. The problem is when I try to update the user:

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

Hibernate don´t delete the Profile relation if there is an empty set of Profile childrens. Only add the profiles (override the old)... That´s rare... What´s the problem?

Thank you in advance

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

内心荒芜 2024-12-28 21:18:09

您实际上所做的就是删除关系,因此没有 DELETE 进行级联,这就是为什么没有删除任何内容。

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

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

编辑

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

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

  1. 清除集合
  2. 将“新”集合添加到重用且现在已清除的集合中,使用 < code>addAll(...)

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

All you actually do is remove the relation and thus theres no DELETE to cascade, that's why nothing gets deleted.

Try adding the Hibernate cascade type DELETE_ORPHAN (using the @Cascade annotation) to make Hibernate delete entities that are not referenced anymore.

Additionally, I'd not remove the Mini entities alone. If there's no relation, i.e. the set of Minis is empty, it normally makes no sense to keep the SuperMini entities that now represent an empty collection (in rare cases it might make sense, just want you to think about whether you need them or not).

Edit:

Note that with DELETE_ORPHAN you should reuse the set, otherwise all the relations might be deleted and reinserted.

Basically Hibernate would then see the set being changed and would issue a delete for the "old" set and a reinsert for the "new" set. This could be wanted but in case you only want an update, i.e. only delete the entities that are not in the set anymore, you should do the following:

  1. clear the set
  2. add the "new" set to the reused and now cleared set using addAll(...)

This should trigger the update (and deletion of orphans) only.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文