Uni- and Bi-directional relations

We have to distinguish between uni-directional and bi-directional relations.

Uni-directional

Uni-directional is a relation where one side does not know about the relation.

public class Computer {
   private Integer id;
   private String name;
... snip ....
public class Developer  {
   private Integer id;
   private String name;
   private List computers = new ArrayList();
.... snip ....

In this case you can only set or delete the relation on one side

developer.getComputers().add(computer);

or

developer.getComputers().remove(computer);

Foreign key constraints

When there is a foreign key constraint on the relation, you must specify nullable=false in the JoinColumn annotation or add not-null="true" in the key tag.

Annotation mapping. 

@OneToMany(cascade = CascadeType.ALL)
@JoinColumn(name = "developer_id", nullable=false)
@IndexColumn(name = "listindex")
private List<Computer> computers = new ArrayList<Computer>();

XML mapping. 

<set name="computers" table="tcomputer" >
  <key column="developer_id" not-null="true"></key>
  <one-to-many class="Computer"/>
</set>

Bi-directional

In a bi-directional relation both sides know about the other side.

public class Computer {
   private Integer id;
   private String name;
 private Developer developer;
... snip ....
public class Developer  {
   private Integer id;
   private String name;
   private List computers = new ArrayList();
.... snip ....

In this case you must always set the relation on both sides. If you do not do this your session will contain false data!

developer.getComputers().add(computer);
computer.setDeveloper(developer);

or

developer.getComputers().remove(computer);
computer.setDeveloper(null);

When a computer cannot exist without a developer, i.e. the foreign key has a not null constraint, then the following will delete the relation.

developer.getComputers().remove(computer);
session.delete(computer);

Foreign key constraints In a bi-directional relation Hibernate can cause exceptions of type foreign key violations. To prevent this you must use inverse="true" on the many side. Inverse=true defines that a side does not manage a relation. In our example, the department side below is not responsible for the relation and team will not be saved, if only the department is saved. You must save the team to have the relation set or use cascade on the department side.

class department. 

    <set name="teams" table="tteam" inverse="true">
      <key column="department_id"></key>
      <one-to-many class="Team"/>
    </set>
... snip ....

class team. 

    <many-to-one name="department" class="Department">
    <column name="department_id" not-null="true"></column>
    </many-to-one>