Hibernate Many-to-many association: left hand side collection contains elements, but right hand side collection is empty

纵然是瞬间 提交于 2019-11-30 13:55:42

The problem probably comes from the fact that you mapped the same bidirectional association twice. If you tell Hibernate twice about the same join table or join column, there is a problem. In a bidirectional association, one of the ends of the association must map the association, and the other one must tell Hibernate that it's the inverse of the other end, using the mappedBy attribute.

Since a many-to-many is completely symmetric, choose one of the end to be the owner (i.e. the end which maps the association, and thus have the @JoinTable annotation). The other side is just the inverse, and thus doesn't have a @JoinTable annotation, but has a mappedBy attribute.

Example:

@Entity
@Table
public class User extends BusinessObject {

    ... 

    // This end is the owner of the association
    @ManyToMany
    @JoinTable(name= "user_role",
               joinColumns = {@JoinColumn(name="user_id")},
               inverseJoinColumns = {@JoinColumn(name="role_id")})  
    private Set<Role> roles = new HashSet<Role>();      
    ... 
}

@Entity
@Table
public class Role extends BusinessObject {
    ...

    // This end is not the owner. It's the inverse of the User.roles association
    @ManyToMany(mappedBy = "roles")
    private Set<User> users = new HashSet<User>();          

    ... 
}

Additional notes:

  • targetEntity isn't useful, since Hibernate knows it thanks to the generic type of the Set. It would be useful if the Set was a Set<SomeInterface>
  • CascadeType.ALL is certainly not what you want. Do you want to delete all the roles of a user when deleting a user? What should happen to the other users having these roles?
  • You should almost always initialize both ends of a bidirectional association. Hibernate takes into account the owner end (i.e. the end without the mappedBy attribute) to persist the association.
  • All of this is explained in the Hibernate reference documentation. Read it: it's full of useful information, and is not hard to understand.

When dealing with a bidirectional many-to-many association you have to maintain both ends of the association. In your case, you have to add the user to the role as well. Adding the role to the user isn't sufficient to establish a bidirectional association as you can read in book Java Persistance with Hibernate:

As always, a bidirectional association (no matter of what multiplicity) requires that you set both ends of the association.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!