Java Persistence/OneToMany

=OneToMany=

A  relationship in Java is where the source object has an attribute that stores a collection of target objects and if those target objects had the inverse relationship back to the source object it would be a   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  relationship, which is similar to a   relationship except that the inverse relationship (if it were defined) is a   relationship. The main difference between a  and a   relationship in JPA is that a   always makes use of an intermediate relational join table to store the relationship, whereas a   can either use a join table, or a foreign key in target object's table referencing the source object table's primary key. If the  uses a foreign key in the target object's table JPA requires that the relationship be bi-directional (inverse   relationship must be defined in the target object), and the source object must use the   attribute to define the mapping.

In JPA a  relationship is defined through the   annotation or the   element.

Example of a OneToMany relationship database
EMPLOYEE (table)

PHONE (table)

Example of a OneToMany relationship and inverse ManyToOne XML
Note this  mapping requires an inverse   mapping to be complete, see ManyToOne.

Getters and Setters
The relationship is bi-directional so, as the application updates one side of the relationship, the other side should also get updated, and be in sync. In JPA, as in Java in general it is the responsibility of the application, or the object model to maintain relationships. If your application adds to one side of a relationship, then it must add to the other side.

This can be resolved through add or set methods in the object model that handle both sides of the relationships, so the application code does not need to worry about it. There are two ways to go about this, you can either only add the relationship maintenance code to one side of the relationship, and only use the setter from one side (such as making the other side protected), or add it to both sides and ensure you avoid an infinite loop.

For example:

Some expect the JPA provider to have magic that automatically maintains relationships. This was actually part of the EJB CMP 2 specification. However the issue is if the objects are detached or serialized to another VM, or new objects are related before being managed, or the object model is used outside the scope of JPA, then the magic is gone, and the application is left figuring things out, so in general it may be better to add the code to the object model. However some JPA providers do have support for automatically maintaining relationships.

In some cases it is undesirable to instantiate a large collection when adding a child object. One solution is to not map the bi-directional relationship, and instead query for it as required. Also some JPA providers optimize their lazy collection objects to handle this case, so you can still add to the collection without instantiating it.

Join Table
A common mismatch between objects and relational tables is that a  does not require a back reference in Java, but requires a back reference foreign key in the database. Normally it is best to define the  back reference in Java, if you cannot or don't want to do this, then you can use an intermediate join table to store the relationship. This is similar to a  relationship, but if you add a unique constraint to the target foreign key you can enforce that it is.

JPA defines a join table using the  annotation and   XML element. A  can be used on a   or   mappings.

See also, Undirectional OneToMany

Example of a OneToMany using a JoinTable database
EMPLOYEE (table)

EMP_PHONE (table)

PHONE (table)

Object not in collection after refresh.

 * See Object corruption.

=Advanced=

Unidirectional OneToMany, No Inverse ManyToOne, No Join Table (JPA 2.x ONLY)
JPA 1.0 does not support a unidirectional  relationship without a. Since JPA 2.0 there is a support for unidirectional. In JPA 2.x a  can be used on a   to define the foreign key, some JPA providers may support this already.

The main issue with an unidirectional  is that the foreign key is owned by the target object's table, so if the target object has no knowledge of this foreign key, inserting and updating the value is difficult. In a unidirectional  the source object take ownership of the foreign key field, and is responsible for updating its value.

The target object in a unidirectional  is an independent object, so it should not rely on the foreign key in any way, i.e. the foreign key cannot be part of its primary key, nor generally have a not null constraint on it. You can model a collection of objects where the target has no foreign key mapped, but uses it as its primary key, or has no primary key using a  collection mapping, see Embeddable Collections.

If your JPA provider does not support unidirectional  relationships, then you will need to either add a back reference   or a. In general it is best to use a  if you truly want to model a unidirectional   on the database.

There are some creative workarounds to defining a unidirectional. One is to map it using a, but make the target table the. This will cause an extra join, but work for the most part for reads, writes of course will not work correctly, so this is only a read-only solution and a hacky one at that.

Example of a JPA 2.x unidirectional OneToMany relationship database
EMPLOYEE (table)

PHONE (table)

Example for a non-null join column
In case your join column is non-null you need to specify

/Mapping