hibernate - 为什么我的多级继承映射没有像我期望的那样工作?

标签 hibernate orm coldfusion coldfusion-10

我有以下实体映射:

// user.cfc
component persistent="true" table="user" discriminatorColumn="userTypeID" {

    property name="id" column="userID" fieldtype="id" generator="identity";
    property name="type" fieldtype="many-to-one" cfc="userType" fkcolumn="userTypeID";

}

// admin.cfc
component extends="user" persistent="true" table="admin" joincolumn="userID" discriminatorValue="3" {

    property name="id" column="adminID" fieldtype="id" generator="identity";

}

// employee.cfc
component extends="user" persistent="true" table="employee" joincolumn="userID" discriminatorValue="0" {

    property name="id" column="employeeID" fieldtype="id" generator="identity";

}

// manager.cfc
component extends="employee" persistent="true" table="manager" joincolumn="employeeID" discriminatorValue="1" {

    property name="id" column="managerID" fieldtype="id" generator="identity";

}

// intern.cfc
component extends="employee" persistent="true" table="intern" joincolumn="employeeID" discriminatorValue="2" {

    property name="id" column="internID" fieldtype="id" generator="identity";

}

根据 Henry 的建议,这里是生成的 hbmxml 文件:

<!-- user.hbmxml -->
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
                                   "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
    <class entity-name="user" lazy="true"
        name="cfc:user" table="user">
        <id name="ID" type="int">
            <column name="userID"/>
            <generator class="identity"/>
        </id>
        <discriminator column="userTypeID"/>
        <many-to-one class="cfc:userType"
            column="userTypeID" insert="false" name="type" update="false"/>
    </class>
</hibernate-mapping>


<!-- admin.hbmxml -->
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
                                   "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
    <subclass discriminator-value="3" entity-name="admin"
        extends="cfc:user" lazy="true" name="cfc:admin">
        <join table="admin">
            <key column="userID"/>
        </join>
    </subclass>
</hibernate-mapping>


<!-- employee.hbmxml -->
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
                                   "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
    <subclass discriminator-value="0" entity-name="employee"
        extends="cfc:user" lazy="true" name="cfc:employee">
        <join table="employee">
            <key column="userID"/>
        </join>
    </subclass>
</hibernate-mapping>


<!-- manager.hbmxml -->
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
                                   "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
    <subclass discriminator-value="1" entity-name="manager"
        extends="cfc:employee" lazy="true" name="cfc:manager">
        <join table="manager">
            <key column="employeeID"/>
        </join>
    </subclass>
</hibernate-mapping>


<!-- intern.hbmxml -->
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
                                   "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
    <subclass discriminator-value="2" entity-name="intern"
        extends="cfc:employee" lazy="true" name="cfc:intern">
        <join table="intern">
            <key column="employeeID"/>
        </join>
    </subclass>
</hibernate-mapping>

如果从映射中看不清楚,关系如下:

user
 |- admin
 |- employee
  |- manager
  |- intern

目的是让 user 实体的 type 属性由 managerintern 的鉴别器值填充 实体。 employee 的构造函数中有代码阻止它被直接实例化,因此 user 将始终有一个 type

当从数据库中读取一些已经存在的数据时,整个映射工作正常。但是,当我尝试插入新记录时遇到问题。

假设涉及的表已经填充了一些记录:

user
|---------------------|
| userID | userTypeID |
|---------------------|
| 1      | 1          |
| 2      | 2          |
| 3      | 2          |
| 4      | 3          |
|---------------------|

admin
|------------------|
| adminID | userID |
|------------------|
| 1       | 4      |
|------------------|

employee
|---------------------|
| employeeID | userID |
|---------------------|
| 1          | 1      |
| 2          | 2      |
| 3          | 3      |
|---------------------|

manager
|------------------------|
| managerID | employeeID |
|------------------------|
| 1         | 1          |
|------------------------|

intern
|-----------------------|
| internID | employeeID |
|-----------------------|
| 1        | 2          |
| 2        | 3          |
|-----------------------|

如果我要创建一个新的 intern 实体并保留它,我希望插入三个记录:

INSERT user ( userID, userTypeID ) VALUES ( 5, 2 )
INSERT employee ( employeeID, userID ) VALUES ( 4, 5 )
INSERT intern ( internID, employeeID ) VALUES ( 3, 4 )

但是,实际执行的SQL是这样的:

INSERT user ( userID, userTypeID ) VALUES ( 5, 2 )
INSERT employee ( employeeID, userID ) VALUES ( 4, 5 )
INSERT intern ( internID, employeeID ) VALUES ( 3, 5 ) -- using the new userID instead of the new employeeID

最后,真正的问题:

为什么插入intern时,使用的是userID而不是employeeID?就好像 Hibernate 忽略了 intern 上的 joincolumn 属性,而只是使用 employeejoincolumn

最佳答案

Hibernate 将使用 User 表中的 discriminatorColumn 来构造一个“intern”对象,因此它使用 userID 而不是 employeeID。

关于hibernate - 为什么我的多级继承映射没有像我期望的那样工作?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20747973/

相关文章:

java - 由 : org. hibernate.TransientObjectException : The given object has a null identifier: com. models.User on hibernate update 引起

c# - 如何使用 Oracle Entity Framework 支持强制使用 pascal 大小写?

sql-server - Coldfusion "can' t find object”错误,但可以在代码的其他部分找到

ColdFusion 字符编码问题

iis - ColdFusion 9 在 Tomcat 7 上的 ODBC 套接字数据源问题

java hibernate 无法解析属性

java - @ManyToOne JPA 关联和级联...不确定如果我删除一个对象会发生什么

java - 尝试使用 Hibernate 执行 SELECT 操作时出错

java - getTransaction().begin()/.commit() 和 joinTransaction() 与 JPA2/EclipseLink 之间有区别吗?

php - 学说 2 : reattaching entities through value objects