javaspringhibernatespring-bootjpa

Hibernate doesn't creating Join Table on his own


I want to make many-to-many relationship between my entities. I want hibernate to generate this table automaticaly, but it's not gonna happen. Here is my entities:

DrugsEntity:

@Entity
@Table(name = "drugs", schema = "meds", catalog = "chinamed")
public class DrugsEntity {
    @Id
    @Basic
    @Column(name = "id")
    private int id;
    @Basic
    @Column(name = "name_eng")
    private String nameEng;

    @ManyToMany()
    @JoinTable(name = "drug_symptom",
            joinColumns = { @JoinColumn(name = "drug_id",nullable = false) },
            inverseJoinColumns = { @JoinColumn(name = "symptom_id", nullable = false) })
    private Set<SymptomEntity> symptoms;
}

SymptomsEntity:

@Entity
@Table(name = "symptom",schema = "meds", catalog = "chinamed")
public class SymptomEntity {

    @Id
    @GeneratedValue
    int id;

    @Basic
    String name;

    @Column
    @ManyToMany(mappedBy = "symptoms",cascade = CascadeType.ALL)
    Set<DrugsEntity> drugs;
}

Some configuration:

jpa:
hibernate:
  ddl-auto: update
show-sql: true

So i can see hibernate sql queries:

Hibernate: create table meds.diseases (disease_id int4 not null, drug_id int4, name varchar(255), primary key (disease_id))
Hibernate: create table meds.drugs (id int4 not null, action_pharm varchar(255), action_tkm varchar(255), clinic varchar(255), contraindications varchar(255), form varchar(255), maker varchar(255), name_eng varchar(255), name_ru varchar(255), taking_method varchar(255), primary key (id))
Hibernate: create table meds.herbal_drug (herbal_id int4 not null, drug_id int4, primary key (herbal_id))
Hibernate: create table meds.pattern_drug (pattern_id int4 not null, drug_id int4, primary key (pattern_id))
Hibernate: create table meds.symptom (id int4 not null, name varchar(255), primary key (id))
Hibernate: alter table if exists symptom_drug add constraint FKl7jx9kgpfiunb1r5neejqi1in foreign key (drug_id) references meds.symptom
Hibernate: alter table if exists symptom_drug add constraint FKimmnf4263cgg3yg46i90tkn1g foreign key (symptom_id) references meds.drugs
Hibernate: alter table if exists symptom_drugs add constraint FKnvs2tystmth11i573t29rtayk foreign key (drugs_id) references meds.drugs
Hibernate: alter table if exists symptom_drugs add constraint FKng4i6ig5nr2laew225ttfnrb9 foreign key (symptom_entity_id) references meds.symptom

As I see hibernate dont even try to create this table.

Using dialect: org.hibernate.dialect.PostgreSQL10Dialect

How can achive that hibernate create that table on his own?

P.S: already looked this link Hibernate doesn't create join table But it isn't my case, i suppose.

SOLVED: The problem was that this table was alredy crated. And I probably coud notice something interesting in hibernate's queries: there was no prefix "meds" before drug_symptom table name. So it created table in "public" schema of databese. Solved that this way: added default_schema

spring:
  jpa:
    hibernate:
      ddl-auto: update
    show-sql: true
    properties:
      hibernate:
        default_schema: meds

But also I could use "schema" parameter in annotation @JoinTable.


Solution

  • Remove @Column annotation from drugs field and define cascade type on DrugsEntity.symptoms, as it is the owning side of relationship.

    Both @JoinTable and @ManyToMany annotations should not be used with @Column, as the mapping must be made by it's own definition. Hibernate gets confused about both annotations on same field.

    Your mapping should be:

     @Entity
     @Table(name = "drugs", schema = "meds", catalog = "chinamed")
     public class DrugsEntity {
          @Id
          @Column(name = "id")
          private int id;
    
         @Basic
         @Column(name = "name_eng")
         private String nameEng;
    
         @ManyToMany(cascade = CascadeType.ALL)
         @JoinTable(name = "drug_symptom",
            joinColumns = @JoinColumn(name = "drug_id",nullable = false),
            inverseJoinColumns = @JoinColumn(name = "symptom_id", nullable = false))
         private Set<SymptomEntity> symptoms;
     }
    

    and

    @Entity
    @Table(name = "symptom",schema = "meds", catalog = "chinamed")
    public class SymptomEntity {
    
        @Id
        @GeneratedValue
        int id;
    
        @Basic
        String name;
    
        @ManyToMany(mappedBy = "symptoms")
        Set<DrugsEntity> drugs;
    }
    

    Good coding!