21

Why hibernate uses a join table for these classes?

@Entity
public class CompanyImpl {
    @OneToMany
    private Set<Flight> flights;


@Entity
public class Flight {

I don't want neither a join table nor a bidirectional association:(

morteza khosravi
  • 1,599
  • 1
  • 20
  • 36

3 Answers3

21

Because that's how it's designed, and what the JPA spec tells it to map such an association. If you want a join column in the Flight table, use

@Entity
public class CompanyImpl {
    @OneToMany
    @JoinColumn(name = "company_id")
    private Set<Flight> flights;
}

This is documented.

JB Nizet
  • 678,734
  • 91
  • 1,224
  • 1,255
  • 5
    "Because that's how it's designed" for me does not seems a reason at all, but a fact :P – Alfonso Nishikawa Mar 02 '16 at 14:27
  • 7
    The reasoning is that, since it's a unidirectional association, the many side doesn't know about the association, and its table should thus not have a column to map that association. – JB Nizet Mar 02 '16 at 15:47
  • @jbnizet I am not satisfied with your reason made in the comment section. Because if the other side don't know about association a table should not have mapping column how would you justify this ? Because unidirectional reverse side is possible i.e many to one.so how does your statement hold good that in unidirectional it is not possible. – JAVA Sep 05 '18 at 12:42
  • 1
    I think reason is it is impossible to maintain the foreign key of the many side table in the one side table.its logically and practically impossible so they gone to create a new join table. Am I correct ?please correct me if am wrong. – JAVA Sep 05 '18 at 12:45
  • @JAVA The reason is not that it's impossible. It is, and my answer explains how to do it. The reason is that it is not desirable: if the many side shouldn't know about the one side, then its table should know either, and should thus not have an additional column to map that association. – JB Nizet Sep 05 '18 at 13:08
  • @JBNizet I would say that it is desirable and any database material that I have read says that in a 1:N relationship, an FK is created in the N side of the relation. Creating an additional table only creates overhead to read, write and maintain the extra table. If this behaviour is not desirable, why would JPA change it when the relation is bidirectional? There is no technical reason to get rid of the extra table. I think it is just a bad decision made by someone. Another thing is that if you have an extra table, you would have to add a constraint so that it doesn't become an N:N relationship. – Jordan Silva Oct 27 '21 at 15:39
5

Hibernate uses an association table to map the relationship, whilst the other table which is the many side does not not that any table exist. It will then create a mapper instead.

The documentation states that using @OneToMany and @ManyToMany you can map Collections, Lists, Maps and Sets of associated entities.

if you do not specify @joincolumn, this is as regards your question, a unidirectional one to many with join table is used. The table name is the concatenation of the owner table name, _, and the other side table name. The foreign key name(s) referencing the owner table is the concatenation of the owner table, _, and the owner primary key column(s) name.

So if you do not want to create a join table(mapper) using the one to many you may have to specify the @joinColumn.

@Entity
public class CompanyImpl {
    @OneToMany
     @JoinColumn(name=flights_id)
    private Set<Flight> flights;


@Entity
public class Flight {
2

I don't think the answers given above are elaborative enough so I hope this helps out

Reason. Why Hibernate creates a join table.

Hibernate creates a Join Table for a unidirectional OneToMany because by implementation, the foreign key is always kept at the many side. So in your example, the foreign key will be kept at the Flight table side AND thus to prevent having null values at the Many side Hibernate chooses to create a JoinTable.

Going by your example,

Every Flight will have a CompanyImpl column and if not set it would have to be null so to achieve the avoid nulls in certain Flight records, Hibernate chooses to have a JoinTable that will store the Ids for Flight and CompanyImpl.

Fahd Jamy
  • 365
  • 6
  • 7
  • But what's the harm in having null values? Effectively it's the same thing. In both implementations I will get null for that flight. – chetan Mar 15 '22 at 15:24