Hibernate不会自动创建联接表

huangapple go评论124阅读模式
英文:

Hibernate doesn't creating Join Table on his own

问题

我想在我的实体之间建立多对多的关系。我希望Hibernate能自动生成这个表,但这似乎不会发生。

这是我的实体:

DrugsEntity

  1. @Entity
  2. @Table(name = "drugs", schema = "meds", catalog = "chinamed")
  3. public class DrugsEntity {
  4. @Id
  5. @Basic
  6. @Column(name = "id")
  7. private int id;
  8. @Basic
  9. @Column(name = "name_eng")
  10. private String nameEng;
  11. @ManyToMany()
  12. @JoinTable(name = "drug_symptom",
  13. joinColumns = { @JoinColumn(name = "drug_id", nullable = false) },
  14. inverseJoinColumns = { @JoinColumn(name = "symptom_id", nullable = false) })
  15. private Set<SymptomEntity> symptoms;
  16. }

SymptomsEntity

  1. @Entity
  2. @Table(name = "symptom", schema = "meds", catalog = "chinamed")
  3. public class SymptomEntity {
  4. @Id
  5. @GeneratedValue
  6. int id;
  7. @Basic
  8. String name;
  9. @Column
  10. @ManyToMany(mappedBy = "symptoms", cascade = CascadeType.ALL)
  11. Set<DrugsEntity> drugs;
  12. }

一些配置:

  1. jpa:
  2. hibernate:
  3. ddl-auto: update
  4. show-sql: true

这样我可以看到Hibernate的SQL查询:

  1. Hibernate: create table meds.diseases (disease_id int4 not null, drug_id int4, name varchar(255), primary key (disease_id))
  2. 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))
  3. Hibernate: create table meds.herbal_drug (herbal_id int4 not null, drug_id int4, primary key (herbal_id))
  4. Hibernate: create table meds.pattern_drug (pattern_id int4 not null, drug_id int4, primary key (pattern_id))
  5. Hibernate: create table meds.symptom (id int4 not null, name varchar(255), primary key (id))
  6. Hibernate: alter table if exists symptom_drug add constraint FKl7jx9kgpfiunb1r5neejqi1in foreign key (drug_id) references meds.symptom
  7. Hibernate: alter table if exists symptom_drug add constraint FKimmnf4263cgg3yg46i90tkn1g foreign key (symptom_id) references meds.drugs
  8. Hibernate: alter table if exists symptom_drugs add constraint FKnvs2tystmth11i573t29rtayk foreign key (drugs_id) references meds.drugs
  9. Hibernate: alter table if exists symptom_drugs add constraint FKng4i6ig5nr2laew225ttfnrb9 foreign key (symptom_entity_id) references meds.symptom

正如我所看到的,Hibernate甚至没有尝试创建这个表。

使用的方言:org.hibernate.dialect.PostgreSQL10Dialect

如何使Hibernate能够自动创建这个表?

附注:已经查看了这个链接 https://stackoverflow.com/questions/52910621/hibernate-doesnt-create-join-table 但这不是我的情况,我想。

已解决:
问题在于这个表已经被创建。我可能可以在Hibernate的查询中注意到一些有趣的东西:在"drug_symptom"表名之前没有前缀"meds"。
所以它在数据库的"public"模式中创建了表。
我通过添加default_schema来解决这个问题。

  1. spring:
  2. jpa:
  3. hibernate:
  4. ddl-auto: update
  5. show-sql: true
  6. properties:
  7. hibernate:
  8. default_schema: meds

但我也可以在@JoinTable注释中使用"schema"参数。

英文:

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:

  1. @Entity
  2. @Table(name = &quot;drugs&quot;, schema = &quot;meds&quot;, catalog = &quot;chinamed&quot;)
  3. public class DrugsEntity {
  4. @Id
  5. @Basic
  6. @Column(name = &quot;id&quot;)
  7. private int id;
  8. @Basic
  9. @Column(name = &quot;name_eng&quot;)
  10. private String nameEng;
  11. @ManyToMany()
  12. @JoinTable(name = &quot;drug_symptom&quot;,
  13. joinColumns = { @JoinColumn(name = &quot;drug_id&quot;,nullable = false) },
  14. inverseJoinColumns = { @JoinColumn(name = &quot;symptom_id&quot;, nullable = false) })
  15. private Set&lt;SymptomEntity&gt; symptoms;
  16. }

SymptomsEntity:

  1. @Entity
  2. @Table(name = &quot;symptom&quot;,schema = &quot;meds&quot;, catalog = &quot;chinamed&quot;)
  3. public class SymptomEntity {
  4. @Id
  5. @GeneratedValue
  6. int id;
  7. @Basic
  8. String name;
  9. @Column
  10. @ManyToMany(mappedBy = &quot;symptoms&quot;,cascade = CascadeType.ALL)
  11. Set&lt;DrugsEntity&gt; drugs;
  12. }

Some configuration:

  1. jpa:
  2. hibernate:
  3. ddl-auto: update
  4. show-sql: true

So i can see hibernate sql queries:

  1. Hibernate: create table meds.diseases (disease_id int4 not null, drug_id int4, name varchar(255), primary key (disease_id))
  2. 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))
  3. Hibernate: create table meds.herbal_drug (herbal_id int4 not null, drug_id int4, primary key (herbal_id))
  4. Hibernate: create table meds.pattern_drug (pattern_id int4 not null, drug_id int4, primary key (pattern_id))
  5. Hibernate: create table meds.symptom (id int4 not null, name varchar(255), primary key (id))
  6. Hibernate: alter table if exists symptom_drug add constraint FKl7jx9kgpfiunb1r5neejqi1in foreign key (drug_id) references meds.symptom
  7. Hibernate: alter table if exists symptom_drug add constraint FKimmnf4263cgg3yg46i90tkn1g foreign key (symptom_id) references meds.drugs
  8. Hibernate: alter table if exists symptom_drugs add constraint FKnvs2tystmth11i573t29rtayk foreign key (drugs_id) references meds.drugs
  9. 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.

  1. Using dialect: org.hibernate.dialect.PostgreSQL10Dialect

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

P.S: already looked this link https://stackoverflow.com/questions/52910621/hibernate-doesnt-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

  1. spring:
  2. jpa:
  3. hibernate:
  4. ddl-auto: update
  5. show-sql: true
  6. properties:
  7. hibernate:
  8. default_schema: meds

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

答案1

得分: 2

从drugs字段中删除@Column注解,并在DrugsEntity.symptoms上定义级联类型,因为它是关系的拥有方。

@JoinTable和@ManyToMany注解都不应与@Column一起使用,因为映射必须通过其自身的定义进行。在同一字段上使用这两个注解会使Hibernate混淆。

您的映射应如下所示:

  1. @Entity
  2. @Table(name = "drugs", schema = "meds", catalog = "chinamed")
  3. public class DrugsEntity {
  4. @Id
  5. @Column(name = "id")
  6. private int id;
  7. @Basic
  8. @Column(name = "name_eng")
  9. private String nameEng;
  10. @ManyToMany(cascade = CascadeType.ALL)
  11. @JoinTable(name = "drug_symptom",
  12. joinColumns = @JoinColumn(name = "drug_id", nullable = false),
  13. inverseJoinColumns = @JoinColumn(name = "symptom_id", nullable = false))
  14. private Set<SymptomEntity> symptoms;
  15. }

  1. @Entity
  2. @Table(name = "symptom", schema = "meds", catalog = "chinamed")
  3. public class SymptomEntity {
  4. @Id
  5. @GeneratedValue
  6. int id;
  7. @Basic
  8. String name;
  9. @ManyToMany(mappedBy = "symptoms")
  10. Set<DrugsEntity> drugs;
  11. }

祝您编码顺利!

英文:

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:

  1. @Entity
  2. @Table(name = &quot;drugs&quot;, schema = &quot;meds&quot;, catalog = &quot;chinamed&quot;)
  3. public class DrugsEntity {
  4. @Id
  5. @Column(name = &quot;id&quot;)
  6. private int id;
  7. @Basic
  8. @Column(name = &quot;name_eng&quot;)
  9. private String nameEng;
  10. @ManyToMany(cascade = CascadeType.ALL)
  11. @JoinTable(name = &quot;drug_symptom&quot;,
  12. joinColumns = @JoinColumn(name = &quot;drug_id&quot;,nullable = false),
  13. inverseJoinColumns = @JoinColumn(name = &quot;symptom_id&quot;, nullable = false))
  14. private Set&lt;SymptomEntity&gt; symptoms;
  15. }

and

  1. @Entity
  2. @Table(name = &quot;symptom&quot;,schema = &quot;meds&quot;, catalog = &quot;chinamed&quot;)
  3. public class SymptomEntity {
  4. @Id
  5. @GeneratedValue
  6. int id;
  7. @Basic
  8. String name;
  9. @ManyToMany(mappedBy = &quot;symptoms&quot;)
  10. Set&lt;DrugsEntity&gt; drugs;
  11. }

Good coding!

huangapple
  • 本文由 发表于 2020年4月6日 09:33:24
  • 转载请务必保留本文链接:https://go.coder-hub.com/61051727.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定