Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Decide which class is owning side in Hibernate

I have Role class, which is the main entity for User's roles and 2 FK in this table, which are pointed on two dictionaries independently: Privelege and Unit classes.

So it's many (Role) to one (Privelege/Unit) relationships as I take.

Qustions:

  1. Is the Hibernate's mapping in my code correct?

  2. Which class is the "owning side" in my case and why?

  3. In which class should I write @JoinColumn and where mappedBy?

As I have read in other posts: "@JoinColumn annotation is maintained in the class which owns the foreign key."

But in Hibernate's doc I see that mappedBy is used on the owning side (see Example 163. Bidirectional @OneToOne). 4. What will happen if I remove some Role records? If I remove some records from dictionaries will it affect Role's records? Can I override this behavior to disable cascading?

I assume that my "Role" class is the owning side because it has FK pointed on 2 dictionaries. So it owns FK. Therefore I need to use @JoinColumn here as its owning side and mappedBy at two dictionaries, because it's mapped by owning side. Am I right.

Update: is the "owning side" synonym to "parent side"?

Role class

@Entity
@Table(name="ROLES_NEW", schema="MAPP")
public class Role implements GrantedAuthority {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "ID", nullable = false)
    private Long id;

    @Column(name = "ROLENAME")
    private String roleName;

    @ManyToOne(fetch = FetchType.EAGER)
    @JoinColumn(name = "UNIT_ID")
    private Unit unit;

    @ManyToOne(fetch = FetchType.EAGER)
    @JoinColumn(name = "PRIVELEGE_ID")
    private Privelege privelege;

...

}

Privelege class


@Entity
@Table(name="PRIVELEGES", schema="MAPP")
public class Privelege /*implements GrantedAuthority*/ {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "ID", nullable = false)
    private Long id;

    @Column(name = "PRIVELEGENAME", length = 255, nullable = false)
    private String privelegeName;

    @Column(name = "descr", length = 255, nullable = false)
    private String descr;

    @OneToMany(mappedBy = "privelege")
    Set<Role> role;

...

}

Unit class

@Entity
@Table(name="UNITS", schema="MAPP")
public class Unit {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "ID", nullable = false)
    private Long id;

    @Column(name = "UNITNAME")
    private String unitname;

    @OneToMany(mappedBy = "unit")
    Set<Role> role;

   ...

}
like image 650
Dec0de Avatar asked Oct 28 '25 16:10

Dec0de


1 Answers

Yes, the child entity owns the relationship, because that's the side the foreign key is on. This mapping is the most efficient in case of @ManyToOne.

Same thing would apply for many-to-many relationships mapped as two bidirectional @ManyToOne. It can also be done with @JoinTable annotation, but this approach is less efficient.

In case of @OneToOne although child (foreign key holder) owns the relationship, the best performance can be obtained, when using @MapsId and @JoinColumn on the parent side. More about that exception can be found here.

When it comes to mappedBy it's simple - it's used when the relationship is bidirectional and on the side @JoinColumn is not (child has @JoinColumn, parent - mappedBy).

I recommend Vlad Mihalcea's blog when it comes to optimal hibernate mapping: one-to-many, many-to-many.

P.S.: Prefer List to Set to map -to-many relationship (source).

like image 96
Andronicus Avatar answered Oct 31 '25 05:10

Andronicus