OneToMany - what are the differences between join table and foreign key?

user652158 picture user652158 · Dec 20, 2011 · Viewed 11.6k times · Source

There is the possibility to disable the @OneToMany relationship join table with the @JoinColumn annotation. The default is a join table.

What are the advantages and disadvantages for a production system for example?
When should I use a join table and when not?

Thank you.

Answer

Piotr Nowicki picture Piotr Nowicki · Dec 20, 2011

By default @OneToMany will create a join table only if you'll use unidirectional relationship.

In other words, if you have Employee and Project entities and the Employee entity is defined as follows (assume there is no orm.xml entries for these entities):

@Entity
public class Employee {
    // ...

    @OneToMany
    Set<Project> projects;
}

@Entity
public class Project {
    // ...
}

the JPA provider will create a join table (notice there is no mappedBy attribute in @OneToMany annotation as there is no reference to Employee entity from the Project).

On the other hand, if you'll use bidirectional relationship:

@Entity
public class Employee {
    // ...

    @OneToMany(mappedBy="employee")
    Set<Project> projects;
}

@Entity
public class Project {
    // ...

    @ManyToOne
    Employee employee;
}

The join table will not be used, as there "many" side will be used to store the foreign key for this relationship.

However, you can force to use join table even in cases when you have bidirectional @OneToMany relationship with defined mappedBy attribute. You can achieve it using @JoinTable annotation on the owning side of the relationship.

There is also a possibility, as you've mentioned, to use @JoinColumn in case where join table would be used by default (unidirectional @OneToMany relationship).

It's best to test the FK and join table performance difference for yourself. I can just guess that less joins (in this case: FK) seems to have better performance.

Moreover, sometimes the DBA defines the database schema and you just need to fit your mappings to the existing schema. Then you have no choice over FK or join table - that's why you have a choice.