Hibernate映射mysql问题 one-to-one

当我们使用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

 

你可能感兴趣的:(Hibernate映射mysql问题 one-to-one)