在每个具体一对一的表类结构中创建外键

2022-09-01 23:54:45

TL;DR如何强制执行 Hibernate 架构创建,以便在下表中为每个具体类设置从 到 为下面显示的结构创建外键约束,而无需向 ?AbstractProperty.ownerIdOwner.ownerIdOwnerAbstractProperty

我正在处理一个项目,其中我具有以下类结构:

Class structure sample

具有到 的 一对一映射,该映射由类扩展(以及其他类似 ,但这与本问题的其余部分并不相关)。OwnerAbstractPropertyConcretePropertyAnotherProperty

实际上只有一个属性,即 .因此,我们希望使用表-per-concrete-class结构,最终得到其他扩展类的 table 、 和 table ()。AbstractPropertyabstractPropertyIdOwnerConcretePropertyAbstractPropertyAnotherProperty

为此,我为以下映射创建了以下映射:Owner

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
    "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
    "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="com.example">
    <class name="Owner">
        <id name="ownerId">
            <generator class="identity"/>
        </id>
        <property name="ownerProperty"/>
        <one-to-one name="abstractProperty"/>
    </class>
</hibernate-mapping>

对于 :AbstractProperty

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
    "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
    "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="com.example">
    <class name="AbstractProperty" abstract="true">
        <id name="ownerId">
            <generator class="foreign">
                <param name="property">ownerId</param>
            </generator>
        </id>
        <union-subclass name="ConcreteProperty">
            <property name="concreteProperty"/>
        </union-subclass>
        <union-subclass name="AnotherProperty">
            <property name="anotherProperty"/>
        </union-subclass>
    </class>
</hibernate-mapping>

这有效。

但是,这是我的问题,使用此映射并让Hibernate为我创建架构(),它不会创建从数据库字段到字段的外键约束。当我创建反向约束的一对一字段时,它从 to 使用此映射 (其中字段在 java 类中是类型):<property name="hbm2ddl.auto">create</property>ConcreteProperty.ownerIdOwner.ownerIdAbstractPropertyOwnerAbstractPropertyownerOwnerAbstractProperty

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
    "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
    "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="com.example">
    <class name="AbstractProperty" abstract="true">
        <id name="ownerId">
            <generator class="foreign">
                <param name="property">ownerId</param>
            </generator>
        </id>
        <one-to-one name="owner" constrained="true"/>
        <union-subclass name="ConcreteProperty">
            <property name="concreteProperty"/>
        </union-subclass>
        <union-subclass name="AnotherProperty">
            <property name="anotherProperty"/>
        </union-subclass>
    </class>
</hibernate-mapping>

如何强制创建外键 from 到,而不在我的字段中使用此字段?AbstractProperty.ownerIdOwner.ownerIdOwnerAbstractProperty


答案 1

简单的答案:永远不要让Hibernate为实际应用程序创建架构。

Hibernate是一个对象关系映射器,应该这样对待它。

Hibernate额外创建模式最多是第一次。但是在第一个版本之后的环境中,您不希望让 Hibernate 控制架构。毕竟,您必须处理SQL才能拥有迁移脚本(手动或工具支持)。在第一个版本发布后,数据库中将有数据。为了确保生产系统上的数据迁移问题更少,您应该在生产环境中以与在开发环境中相同的方式考虑架构和数据迁移。

例外情况可能是任何很少更改数据的应用程序,这些数据可能会在数据丢失时快速重建。


答案 2

我们使用标准的JPA(没有特定于休眠的黑客)并遇到了同样的问题,我们没有找到一个很好的解决方案。

假设:

  1. AbstractProperty是包中的一个类,可在不同的应用程序中重用/共享,并且您不希望引用特定于应用程序的类。Owner
  2. ConcreteProperty & AnotherProperty是特定于应用程序的。

在这种情况下,解决方案是将引用放入(使用外键),最终既扩展相同的引用,又使私有,以便在设置所有者时自动设置它。ConcretePropertyOwnerAnotherPropertyApplicationPropertyabstractPropertyId


推荐