当我们使用hibernate的一对一映射,配置mysql数据库表时:
两表的配置文件如下:
1、tseal:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="com.indigopacific.iessportal.persistent.Seal"
table="tseal" dynamic-update="true" dynamic-insert="true"
select-before-update="false" lazy="false">
<id name="id" column="id" type="long">
<generator class="increment"/>
</id>
<property name="sealName" type="string" column="sealName"
not-null="false" unique="false" />
<one-to-one name="sealData"
class="com.indigopacific.iessportal.persistent.SealData"
cascade="save-update" lazy="proxy">
<set name="sealModels" cascade="save-update" lazy="true"
outer-join="false" inverse="true">
<key column="sealId" />
<one-to-many
class="com.indigopacific.iessportal.persistent.SealModel" />
</set>
<many-to-one name="branchInfo" column="branchInfoId"
class="com.indigopacific.iessportal.persistent.BranchInfo"
cascade="save-update" outer-join="false" lazy="false">
</many-to-one>
</class>
</hibernate-mapping>
2、tsealData
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="com.indigopacific.iessportal.persistent.SealData"
table="tsealdata" dynamic-update="true" dynamic-insert="true"
select-before-update="false" lazy="true">
<id name="id" column="id" type="long">
<generator class="foreign">
<param name="property">seal</param>
</generator>
</id>
<one-to-one name="seal"
class="com.indigopacific.iessportal.persistent.Seal" cascade="save-update" constrained="true"/>
<property name="sealString" type="string" column="sealString"
not-null="false" unique="false" />
</class>
</hibernate-mapping>
如果我们保存tseal表时想同时保存tsealdata表数据,如果写成:
Seal seal = new Seal();
seal.setSealName("seal");
SealData data = new SealData();
data.setSealString("hello");
seal.setSealData(data);
session.save(seal);
会报如下异常:
org.hibernate.id.IdentifierGenerationException: attempted to assign id from null one-to-one property: seal
但是在oracle中不会这样,原因尚待分析。
需要改成如下解决问题:
Seal seal = new Seal();
seal.setSealName("seal");
SealData data = new SealData();
data.setSealString("hello");
seal.setSealData(data);
data.setSeal(seal);
session.save(seal);
并发出如下sql语句:
Hibernate: insert into tseal (sealName, id) values (?, ?)
Hibernate: insert into tsealdata (sealString, id) values (?, ?)
原因是:
当我们保存tseal表时,由于没有提交,导致我们保存tsealdata时将null分配该表记录作为主键,因而报错。
这里如果将constrained="true"放到seal的hibernate mapping文件中保存时会报如下错误:
Caused by: java.sql.SQLException: Cannot add or update a child row: a foreign key constraint fails (`iess`.`tsealdata`, CONSTRAINT `FKDB17E37BF293309C` FOREIGN KEY (`id`) REFERENCES `tseal` (`id`))
at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:2926)
at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:1571)
at com.mysql.jdbc.ServerPreparedStatement.serverExecute(ServerPreparedStatement.java:1120)
at com.mysql.jdbc.ServerPreparedStatement.executeInternal(ServerPreparedStatement.java:675)
at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:1162)
at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:1079)
at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:1064)
at com.mchange.v2.c3p0.impl.NewProxyPreparedStatement.executeUpdate(NewProxyPreparedStatement.java:105)
at org.hibernate.jdbc.NonBatchingBatcher.addToBatch(NonBatchingBatcher.java:23)
at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:2197)
... 27 more