【发布时间】:2009-05-11 17:00:11
【问题描述】:
我有两个旧数据库表,以这样的简化方式布局:
MASTER SLAVE
ident ident
sName sName
sNumber sNumber
sDesc sValue
----- ------
Java Class 'ScenarioMaster' Java Class 'ScenarioSlave'
每一行都有一个通过ident 列的代理索引,但MASTER.key 和SLAVE.key 之间没有关系。但是,对于MASTER 表,一对 sName/sNumber 的唯一性是正确的。因此,这将是一个可能且有意义的复合键(我知道那些是邪恶的)。
实际上,存在 1:n 关系,这意味着每个 MASTER 行引用 SLAVE 表中的 n 行。鉴于上面的列描述,可能的人口可能是
MASTER SLAVE
100 42
'labl' 'labl'
1 1
'some label' 0.1
43
'labl'
1
0.2
现在,使用 hibernate,我如何在我的 java 类中反映这种关系?在ScenarioMaster 中,我会声明一个带有公共 getter/setter 的 Set 或 List,例如
private List<ScenarioSlave> slaves = new ArrayList<ScenarioSlave>();
ScenarioMaster 的休眠映射可能包含
<bag name="slaves" cascade="all">
<key>
<column name="sName" not-null="true"/>
<column name="sNumber" not-null="true"/>
</key>
<one-to-many class="ScenarioSlave"/>
</bag>
但是,这会在使用 session.saveOrUpdate(scenarioMaster) 更新已持久的 ScenarioMaster 实体时创建一个战略更新语句。
// create master scn and slave slv
scn.addSlave(slv);
session.saveOrUpdate(scn);
Hibernate:
update
SLAVE
set
sNumber=?,
sName=?,
sValue=?
where
sName=?
and sNumber=?
Hibernate:
update
SLAVE
set
sName=null,
sNumber=null
where
sName=?
and sNumber=?
我做错了什么?第二次更新来自哪里?
我想这与 sName/sNumber 不是 ScenarioSlave 的键有关。我不太明白,为什么。
请注意,sName/sNumber 参数确实指向有效值,并且我想通过saveOrUpdate 持久化的ScenarioMaster 实例实际上在slaves 列表中有一个非空ScenarioSlave 实例。
编辑:使用此映射将复合键推迟到单独的类
<composite-id name="keyId" class="ScenarioKeyId">
<key-property name="name" access="field" column="sName"
type="string" length="20"/>
<key-property name="number" access="field" column="sNumber"
type="long"/>
</composite-id>
我真的不想创建一个表 NAMENUMBER_KEY 将 'labl', 1 映射到类似 'key_labl1' 的东西,然后可以用作@ 987654343@ 用于休眠。我想,这就是 hibernate 所做的(不使用实际的表)。
【问题讨论】:
标签: hibernate database-design orm