Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JPA Annotations for many-to-many relation between objects of the same entity

I want to implement a Role Hierarchy but am rather new to JPA Annotations.

I have a Role Entity with a name and an id(implicit via AbstractPersistable):

@Entity
@Table(name="role")
public class Role extends AbstractPersistable<Long> {
    private static final long serialVersionUID = 8127092070228048914L;  
    private String name;

Now I want to be able to define the following relationships:

  • a Role can have many child roles
  • a Role can be child to many roles

How would I do that with Hibernate annotations? Can I define this inside the Role Entity

@ManyToMany(cascade = CascadeType.MERGE)
@JoinTable( name = "role_hierarchy", 
            joinColumns = { @JoinColumn(name = "role_id")}, 
            inverseJoinColumns={@JoinColumn(name="child_role_id")})  
private List<Role> roles;

@ManyToMany(cascade = CascadeType.MERGE)
@JoinTable( name = "role_hierarchy", 
            joinColumns = { @JoinColumn(name = "child_role_id")}, 
            inverseJoinColumns={@JoinColumn(name="role_id")})  
private List<Role> children;

Am I on the right track? What am I missing?

Thank's a lot for your help!


EDIT: - removed as it has been solved -


EDIT 2:

Looks like I have some bug in my application stack. On the model defining level the role_hierarchy is working out just fine, so never mind EDIT 1...

BUT: Both ways seem to work (that is createing the m:n table entry, cascading delete and retrieval of parents and children for an entity):

  • my proposal of defining a join column for both sides with no mappedBy property at the @ManyToMany annotation
  • as well as defining an owning side and an inverse side.

What's the difference? Does it matter?

like image 582
Pete Avatar asked Dec 09 '22 05:12

Pete


1 Answers

Bidirectional relationship consists of owning and inverse sides.

At the owning side you declare physical properties of the relationship:

@ManyToMany(cascade = CascadeType.MERGE)
@JoinTable(name = "role_hierarchy", 
            joinColumns = { @JoinColumn(name = "role_id")}, 
            inverseJoinColumns={@JoinColumn(name="child_role_id")})  
private List<Role> roles;

At the inverse side you point at the corresponding owning side with mappedBy attribute:

@ManyToMany(cascade = CascadeType.MERGE, mappedBy = "roles")
private List<Role> children;    

For many-to-many relationships it doesn't matter which side is the owning side (as long as you modify both sides consistently, since only changes at the owning side are propagated to the database).

See also:

  • 2.2.5.3.2. Many-to-many
like image 75
axtavt Avatar answered Apr 23 '23 08:04

axtavt