【问题标题】:Changing the generated name of a foreign key in Hibernate在 Hibernate 中更改生成的外键名称
【发布时间】:2013-05-10 00:13:52
【问题描述】:
@OneToOne()
@JoinColumn(name="vehicle_id", referencedColumnName="vehicleId")
public Vehicle getVehicle() {
    return vehicle;
}

我的 UserDetails 类与实体类 Vehicle 具有一对一的映射关系。 Hibernate 创建 2 个表并分配一个通用外键,它将 vehicle_id 列(UserDetails 表。)映射到主键 vehicleId(Vehicle 表)。

KEY FKB7C889CEAF42C7A1 (vehicle_id),
CONSTRAINT FKB7C889CEAF42C7A1 FOREIGN KEY (vehicle_id) REFERENCES vehicle (vehicleId)

我的问题是:我们如何将生成的外键更改为有意义的东西,例如 Fk_userdetails_vehicle。

【问题讨论】:

  • @Ashok_udhay 由于与外键有关的错误通常只会导致外键的名称被数据库吐出,因此命名键可以让您了解键的用途,而无需首先在您的数据库创建脚本中跟踪它。
  • 只是为了好奇(而且可能太明显而无法说明);众所周知,Hibernate 使用表和属性名称来生成其约束/外键名称 (source);所以看似“随机”的名称实际上将保持不变,除非您实际更改架构。 MD5 步骤使最终结果“没有意义”,或者更确切地说是“人类不可读”。

标签: java mysql hibernate


【解决方案1】:

从 JPA 2.1 开始,您可以使用 @javax.persistence.ForeignKey 注释:

@OneToOne()
@JoinColumn(name="vehicle_id", referencedColumnName="vehicleId", foreignKey=@ForeignKey(name = "Fk_userdetails_vehicle"))
public Vehicle getVehicle() {
    return vehicle;
}

在 JPA 2.1 之前,您可以使用 Hibernate 的 @org.hibernate.annotations.ForeignKey 注释,但现在已弃用:

@OneToOne()
@JoinColumn(name="vehicle_id", referencedColumnName="vehicleId")
@ForeignKey(name="Fk_userdetails_vehicle")
public Vehicle getVehicle() {
   return vehicle;
}

【讨论】:

  • The annotation @ForeignKey is disallowed for this location.
  • 使用hibernate外键注解,不要使用javax.persistence.ForeignKey,这样就可以了
  • 这个答案使用了已弃用的、特定于 Hibernate 的 API,而不是现成的符合 JPA 的 API。 2013 年可能还不错,但现在不再是最佳答案了。
  • 如何使用 JPA 项目从数据库中自动生成这个 @ForeignKey 名称?
【解决方案2】:

您也可以像这样使用嵌入在@JoinColumn 中的@ForeignKey:

@JoinColumn(name = "BAR_ID", foreignKey = @ForeignKey(name = FK_BAR_OF_FOO))

对于@ManyToMany 关系,您可以使用嵌入在@JoinTable 中的foreignKey 和inverseForeignKey,如下所示:

@JoinTable(name = "ARC_EMPLOYEE_OF_BAR"
        , joinColumns = {@JoinColumn(name = "BAR_ID")}
        , inverseJoinColumns = {@JoinColumn(name = "EMPLOYEE_ID")}
        , uniqueConstraints = {@UniqueConstraint(name = "ARC_UK_EMPLOYEE_OF_BAR", columnNames = {"EMPLOYEE_ID", "BAR_ID"})}
        , foreignKey = @ForeignKey(name = "ARC_FK_BAR_OF_EMPLOYEE")
        , inverseForeignKey = @ForeignKey(name = "ARC_FK_EMPLOYEE_OF_BAR"))

【讨论】:

  • 谢谢。使用 javax.persistence.*
  • 对我不起作用 (ManyToMany)。 Hibernate 仍然尝试使用自己的名称创建 FK 约束。
  • 这也适用于使用交集表的@OneToMany 关系。
【解决方案3】:

您也可以通过实现ImplicitNamingStrategy.determineForeignKeyName 并使用

configuration.setImplicitNamingStrategy(
    new MyImplicitNamingStrategy())

这很好,因为您不必一次又一次地手动操作。但是,可能很难将相关信息放在那里。我试图连接我得到的所有东西(使用三个下划线分隔部分)并最终得到

FK_ACCESS_TEMPLATE____TEMPLATE____TEMPLATE_ID____TEMPLATE_ID__INDEX_B

这并不比

FKG2JM5OO91HT64EWUACF7TJCFN_INDEX_B

我想,只使用引用的表和列名以及唯一性数字就可以了。


还要注意,这似乎是遗留的 Hibernate 东西,不受 JPA 支持。

OTOH 它适用于 Hibernate 5.0.1(仅一周)。

【讨论】:

    【解决方案4】:

    也许你应该试试这个,添加@ForeignKey 注释:

    @ManyToOne
    @ForeignKey(name="FK_some_model")
    @JoinColumn(name="some_model_id")
    private SomeModel someModel
    

    【讨论】:

      猜你喜欢
      • 2013-05-10
      • 2016-08-14
      • 2021-04-26
      • 2016-06-08
      • 1970-01-01
      • 2020-10-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多