Java Persistence/ManyToOne
Contents |
[edit] ManyToOne
A ManyToOne relationship in Java is where the source object has an attribute that references another target object and (if) that target object had the inverse relationship back to the source object it would be a OneToMany relationship. All relationships in Java and JPA are unidirectional, in that if a source object references a target object there is no guarantee that the target object also has a relationship to the source object. This is different than a relational database, in which relationships are defined through foreign keys and querying such that the inverse query always exists.
JPA also defines a OneToOne relationship, which is similar to a ManyToOne relationship except that the inverse relationship (if it were defined) is a OneToOne relationship. The main difference between a OneToOne and a ManyToOne relationship in JPA is that a ManyToOne always contains a foreign key from the source object's table to the target object's table, where as a OneToOne relationship the foreign key may either be in the source object's table or the target object's table.
In JPA a ManyToOne relationship is defined through the @ManyToOne annotation or the <many-to-one> element.
In JPA a ManyToOne relationship is always (well almost always) required to define a OneToMany relationship, the ManyToOne always defines the foreign key (JoinColumn) and the OneToMany must use a mappedBy to define its inverse ManyToOne.
[edit] Example of a ManyToOne relationship database
EMPLOYEE (table)
| EMP_ID | FIRSTNAME | LASTNAME | SALARY | MANAGER_ID |
| 1 | Bob | Way | 50000 | 2 |
| 2 | Sarah | Smith | 75000 | null |
PHONE (table)
| ID | TYPE | AREA_CODE | P_NUMBER | OWNER_ID |
| 1 | home | 613 | 792-0000 | 1 |
| 2 | work | 613 | 896-1234 | 1 |
| 3 | work | 416 | 123-4444 | 2 |
[edit] Example of a ManyToOne relationship annotations
@Entity public class Phone { @Id private long id; ... @ManyToOne(fetch=FetchType.LAZY) @JoinColumn(name="OWNER_ID") private Employee owner; ... }
[edit] Example of a ManyToOne relationship XML
<entity name="Phone" class="org.acme.Phone" access="FIELD"> <attributes> <id name="id"/> <many-to-one name="owner" fetch="LAZY"> <join-column name="OWNER_ID"/> </many-to-one> </attributes> </entity>
[edit] See Also
[edit] Common Problems
[edit] Foreign key is also part of the primary key.
[edit] Foreign key is also mapped as a basic.
- If you use the same field in two different mappings, you typically require to make one of them read-only using
insertable, updateable = false. - See Target Foreign Keys, Primary Key Join Columns, Cascade Primary Keys.
[edit] Constraint error on insert.
- This typically occurs because you have incorrectly mapped the foreign key in a
OneToOnerelationship.
- It can also occur if your JPA provider does not support referential integrity, or does not resolve bi-directional constraints. In this case you may either need to remove the constraint, or use
EntityManagerflush()to ensure the order your objects are written in.
[edit] Foreign key value is null
- Ensure you set the value of the object's
OneToOne, if theOneToOneis part of a bi-directionalOneToManyrelationship, ensure you set the object'sOneToOnewhen adding an object to theOneToMany, JPA does not maintain bi-directional relationships for you. - Also check that you defined the
JoinColumncorrectly, ensure you did not setinsertable, updateable = falseor use aPrimaryKeyJoinColumn.
[edit] Advanced
[edit] Target Foreign Keys, Primary Key Join Columns, Cascade Primary Keys
In complex data models it may be required to use a target foreign key, or read-only JoinColumn in mapping a ManyToOne if the foreign key/JoinColumn is shared with other ManyToOne or Basic mappings.
See, Target Foreign Keys, Primary Key Join Columns, Cascade Primary Keys
This page may need to be 