【发布时间】:2014-01-11 22:24:30
【问题描述】:
我有以下实体映射:
// 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 属性由manager 和intern 实体的鉴别器值填充。 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 属性,只使用来自 employee 的 joincolumn。
【问题讨论】:
-
为了帮助 hibernate 的人帮助你,你可能需要考虑发布
.hbxmlCF 生成。 -
@Henry - 好主意,已添加。
-
我可能是错的,但我相信这就是hibernate的工作原理。这背后有他们的原因。所以要么喝 koolaid 并坚持他们给你的东西,要么简化你的设计。
-
@Henry - 澄清一下,“这就是 hibernate 的工作原理”,您的意思是您认为 hibernate 有意忽略第一级继承之外的连接列?
-
是的。 Hibernate 将使用 User 表中的 discriminatorColumn 来构造一个“实习生”,因此它使用 userID。
标签: hibernate orm coldfusion coldfusion-10