Search code examples
javahibernatejpaassociationspersistence

Non-owning entity side of @OneToOne/@ManyToOne/@ManyToMany


I am trying to understand the javax.persistence annotations @OneToOne, @ManyToOne and @ManyToMany. The descriptions for these annotations make a mention of non-owning side. Specifically:

[@OneToOne]: If the relationship is bidirectional, the non-owning side must use the mappedBy element of the OneToOne annotation to specify the relationship field or property of the owning side.

[@ManyToOne]: If the relationship is bidirectional, the non-owning OneToMany entity side must used the mappedBy element to specify the relationship field or property of the entity that is the owner of the relationship.

[@ManyToMany]: If the relationship is bidirectional, the non-owning side must use the mappedBy element of the ManyToMany annotation to specify the relationship field or property of the owning side.

I am having trouble understanding this ownership aspect. For example, I have the following associations:

OneToOne

ManyToOne

enter image description here

Note: Images taken from here.


So which are the non-owning entity sides of these associations?


Solution

  • In the bi-directional relationship betweens two objects ,you have to choose which sides to manage the relationship. From the database perspective , managing the relationship means managing the value of some FK column that link between two tables. The side that managing it is called owning side. Otherwise, it is call non-owning side.

    So back to your example on ProjectManager and Project. Which object is the owning side depends on which object you choose to manage their relationship.

    If you choose ProjectManager to be the owning side (hence Project is the non-owning side), only the values of ProjectManager#getProjects() will be used to determine the value of such FK column. (i.e. project table 's project_manager_id column in this case) The value of Project#getProjectManager() will be ignored and does not affect the value of this FK column.

    In term of JPA mapping , it is :

    @Entity
    @Table(name="project_manager")
    public class ProjectManager{
    
        @OneToMany
        private List<Project> projects = new ArrayList<>();
    
    }
    
    @Entity
    @Table(name="project")
    public class Project {
    
        @ManyToOne
        @JoinColumn(name = "project_manager_id")
        private ProjectManager projectManager;
    }
    

    On the other hands , if you choose Project to the owning side (hence ProjectManager is the non-owning side) , only the value of Project#getProjectManager() will be used to determine the value of this FK column while the value of ProjectManager#getProjects() will be ignored. The JPA mapping in the case will be :

    @Entity
    @Table(name="project_manager")
    public class ProjectManager{
    
        @OneToMany(mappedBy="projectManager")
        private List<Project> projects = new ArrayList<>();
    
    }
    
    @Entity
    @Table(name="project")
    public class Project {
    
        @ManyToOne
        @JoinColumn(name = "project_manager_id")
        private ProjectManager projectManager;
    }
    

    P.S: I explain it using property access , hopefully you should get the idea.