ericj
ericj

Reputation: 2301

How to make a one-to-many bidirectional relation with JPA annotations, where the collection side owns it

I have from the Hibernate docs a mapping in XML. My question is how to do it with JPA annotations. It is a one-to-many bidirectional relation, and the collection side owns it. Thanks.

<class name="Person">
    <id name="id" column="personId">
        <generator class="native"/>
    </id>
    <set name="addresses" 
        table="PersonAddress">
        <key column="personId"/>
        <many-to-many column="addressId"
            unique="true"
            class="Address"/>
    </set>
</class>

<class name="Address">
    <id name="id" column="addressId">
        <generator class="native"/>
    </id>
    <join table="PersonAddress" 
        inverse="true" 
        optional="true">
        <key column="addressId"/>
        <many-to-one name="person"
            column="personId"
            not-null="true"/>
    </join>
</class>

Upvotes: 3

Views: 2042

Answers (1)

Vlad Mihalcea
Vlad Mihalcea

Reputation: 153940

For the case when the collection is the owning side, you need to make the @ManyToOne non-insetable and non-updatable, while removing the mappedBy on the @OneToMany side:

@Entity
@Table(name = "PERSON")
public class Person {

    @Id
    @Column(name = "personId")
    private long id;

    @OneToMany
    private Set<Address> addresses;
}


@Entity
@Table(name = "ADDRESS") 
public class Address {

   @Id
   @Column(name = "addressId")  
   private long id;       

   @ManyToOne
   @JoinColumn(name = "personId", insertable = false, updatable = false)
   private Person person;
}

This mapping should generate a link table, but if you want to override it then use the @JoinTable annotation too:

@Entity
@Table(name = "PERSON")
public class Person {

    @Id
    @Column(name = "personId")
    private long id;

    @OneToMany
    @JoinTable(name="PersonAddress", 
        joinColumns=@JoinColumn(name="personId"),
        inverseJoinColumns=@JoinColumn(name="addressId")
    )
    private Set<Address> addresses;
}


@Entity
@Table(name = "ADDRESS") 
public class Address {

   @Id
   @Column(name = "addressId")  
   private long id;       

   @ManyToOne
   @JoinTable(name="PersonAddress", 
        joinColumns=@JoinColumn(name="addressId", insertable = false, updatable = false),
        inverseJoinColumns=@JoinColumn(name="personId", insertable = false, updatable = false)
   )
   private Person person;
}

Upvotes: 3

Related Questions