У меня есть две устаревшие таблицы базы данных, расположенные в упрощенном виде, например:
MASTER SLAVE
ident ident
sName sName
sNumber sNumber
sDesc sValue
----- ------
Java Class 'ScenarioMaster' Java Class 'ScenarioSlave'
Каждая строка имеет суррогатный индекс через столбец ident
, но между MASTER.key
и SLAVE.key
нет никакой связи. Однако для таблицы MASTER
уникальность одной пары sName / sNumber имеет значение true. Поэтому это был бы возможный и значимый составной ключ (я знаю, что это зло).
Фактически, существует отношение 1: n, означающее, что каждая MASTER
ссылка на строку n строка в таблице SLAVE
. Учитывая описание столбца сверху, возможная совокупность может быть
MASTER SLAVE
100 42
'labl' 'labl'
1 1
'some label' 0.1
43
'labl'
1
0.2
Теперь, используя hibernate, как я могу отразить эти отношения в моих классах Java? В ScenarioMaster
я бы объявил набор или список с общедоступными получателями / установщиками, такими как
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>
Это, однако, создает оператор обновления strage при обновлении уже персистентного объекта ScenarioMaster
с использованием session.saveOrUpdate(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 указывают на допустимые значения и что экземпляр ScenarioMaster
, который я хочу сохранить с помощью saveOrUpdate
, на самом деле имеет ненулевой экземпляр ScenarioSlave
в списке slaves
.
РЕДАКТИРОВАТЬ : составной ключ откладывается в отдельный класс с помощью этого сопоставления
<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' , которую затем можно использовать как id
для зимней спячки. Я полагаю, это то, что делает Hibernate (без использования реальной таблицы).