【问题标题】:Hibernate doesn't create foreign key constraints for @ManyToOneHibernate 不会为 @ManyToOne 创建外键约束
【发布时间】:2026-01-26 04:05:01
【问题描述】:

我有 Hibernate 映射的类,其中 ManyToOne 注释有时会导致数据库中的外键约束(我已经尝试过 Oracle 和 H2),有时不会。

例如这里没有为source_id生成约束:

@Entity
@Table( name = "onto_entry" )
@Inheritance ( strategy = InheritanceType.SINGLE_TABLE )
@DiscriminatorColumn ( name = "term_category" )
@DiscriminatorValue ( "generic" )
@SequenceGenerator( name = "hibernate_seq", sequenceName = "onto_entry_seq" )
public class OntologyEntry extends Identifiable
{
  ...
  @ManyToOne ( targetEntity = ReferenceSource.class, cascade = {   
    CascadeType.MERGE, CascadeType.PERSIST, CascadeType.REFRESH } )
  @JoinColumn( name = "source_id" )
  public ReferenceSource getSource ()
  ...
}

虽然我在这里得到了为 protocol_id 生成的 FK 约束:

@Entity
@Table ( name = "protocol_application" )
public class ProtocolApplication extends Identifiable
{
  @ManyToOne ( cascade = {CascadeType.MERGE, CascadeType.PERSIST, CascadeType.REFRESH}, targetEntity = Protocol.class )
  @JoinColumn ( name = "protocol_id" )
  public Protocol getProtocol ()
  ...
}

我做错了吗?哪些因素会影响这种行为?

【问题讨论】:

  • 你是如何定义关系的另一端的(对于这两种情况)?
  • 本,没有另一面,我不关心在这种情况下从父级到子级,因为它很少需要,可以通过 SQL/HQL 完成。

标签: java hibernate many-to-one


【解决方案1】:

我自己来回答。

Hibernate doesn't create join table indexes in Oracle, unless in create mode。所以我决定自己做,通过查看 JPA 注释部分自动化它。 This 是我目前所做的。

【讨论】:

    【解决方案2】:

    可能 hibernate.dialect 设置为 MyISAM 而不是 InnoDB

    MyISAM 不支持外键。

    这样设置

    hibernate.dialect = org.hibernate.dialect.MySQL5InnoDBDialect
    

    或用于 Spring Boot

    spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.MySQL5InnoDBDialect
    

    【讨论】:

    • 请阅读我的自我回答。它是 Oracle,显然,对于 Oracle 和其他 DBMS,约束和索引仅在创建模式下创建,而不是在更新模式时创建。幸运的是,这些天我不怎么使用 Hibernate。