OneToMany - what are the differences between join

2019-02-09 14:53发布

问题:

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.

回答1:

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.



回答2:

Join tables are needed for polymorphisms. E.g., if Employee and Manager links the same project and they are mapped with one-table-per-class strategy, at the relational DB level, the only way to know that project( id = 1, emp_id = 10 ) refers to a manager is to put emp_id in the manager_2_employee table. If one is not in such a situation, then emp_id can go directly into project.



回答3:

As mentioned in comments above, by default hibernate goes for join table. This results in better db normalization.

If having a choice, JoinColumn gives better performance over the join table as need for the joining of an extra table in the SQL Query is removed.