Hibernate-1VSN关系出现的异常分析

 
 这个小的例子程序包括两个对象

person 、address 它们存在1对N的关系

 

数据库脚本如下:

--删除表
DROP TABLE person;
DROP TABLE address;

--创建表
create table person
(
 pid varchar(32) primary key not null,
 name varchar(20) not null,
 age int not null,
 nowdate timestamp default now() not null
);

create table address
(
 aid varchar(32) primary key not null,
 name varchar(20) not null,
 descirable varchar(100) not null,
 p_id varchar(32) not null references person(pid) on delete cascade
);

 

Person.hbm.xml文件:

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
  3. "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
  4. <!-- 
  5.     Mapping file autogenerated by MyEclipse Persistence Tools
  6. -->
  7. <hibernate-mapping>
  8.     <class name="org.wsj.oneTOmanyHibernateDemo.pojo.Person" table="person" catalog="test">
  9.         <id name="pid" type="string">
  10.             <column name="pid" length="32" />
  11.             <generator class="uuid.hex" />
  12.         </id>
  13.         <property name="name" type="string">
  14.             <column name="name" length="20" not-null="true" />
  15.         </property>
  16.         <property name="age" type="integer">
  17.             <column name="age" not-null="true" />
  18.         </property>
  19.         <property name="nowdate" type="date" insert="false">
  20.             <column name="nowdate" length="10" not-null="true" />
  21.         </property>
  22.         
  23.         <set name="address" table="address" cascade="all" inverse="true">
  24.             <key column="p_id"/>
  25.             <one-to-many class="org.wsj.oneTOmanyHibernateDemo.pojo.Address"/>
  26.         </set>
  27.     </class>
  28. </hibernate-mapping>

Address.hbm.xml文件:

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
  3. "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
  4. <!-- 
  5.     Mapping file autogenerated by MyEclipse Persistence Tools
  6. -->
  7. <hibernate-mapping>
  8.     <class name="org.wsj.oneTOmanyHibernateDemo.pojo.Address"
  9.         table="address" catalog="test">
  10.         <id name="aid" type="string">
  11.             <column name="aid" length="32" />
  12.             <generator class="uuid.hex"></generator>
  13.         </id>
  14.         <property name="name" type="string">
  15.             <column name="name" length="20" not-null="true" />
  16.         </property>
  17.         <property name="descirable" type="string">
  18.             <column name="descirable" length="100" not-null="true" />
  19.         </property>
  20.         
  21.         <many-to-one name="person"
  22.             class="org.wsj.oneTOmanyHibernateDemo.pojo.Person">
  23.             <column name="p_id" />
  24.         </many-to-one>
  25.     </class>
  26. </hibernate-mapping>

PersonAdressOperator .java文件:

  1. package org.wsj.oneTOmanyHibernateDemo.operator;
  2. import java.util.HashSet;
  3. import org.hibernate.Session;
  4. import org.hibernate.cfg.Configuration;
  5. import org.wsj.oneTOmanyHibernateDemo.pojo.Address;
  6. import org.wsj.oneTOmanyHibernateDemo.pojo.Person;
  7. public class PersonAdressOperator {
  8.  private Session session;
  9.  public PersonAdressOperator() {
  10.   this.session = new Configuration().configure().buildSessionFactory()
  11.     .openSession();
  12.  }
  13.  public void add(Person p) {
  14.   
  15.   this.session.save(p); 
  16.   this.session.beginTransaction().commit();
  17.  }
  18.  public static void main(String[] args) {
  19.   
  20.   PersonAdressOperator po = new PersonAdressOperator();
  21.   
  22.   Person p = new Person();
  23.   p.setName("scofield_alex");
  24.   p.setAge(1);
  25.   p.setAddress(new HashSet<Address>());
  26.   
  27.   Address ad = null;
  28.   
  29.   ad = new Address();
  30.   ad.setName("朝阳区");
  31.   ad.setDescirable("朝阳新区");
  32.   ad.setPerson(p);
  33.   p.getAddress().add(ad);
  34. //  
  35. //  ad = new Address();
  36. //  ad.setName("海淀区");
  37. //  ad.setDescirable("海淀新区");
  38. //  ad.setPerson(p);
  39. //  p.getAddress().add(ad);
  40. //  
  41. //  ad = new Address();
  42. //  ad.setName("天安门广场");
  43. //  ad.setDescirable("天安门广场");
  44. //  ad.setPerson(p);
  45. //  p.getAddress().add(ad);
  46.   
  47.   po.add(p);
  48.   
  49.  }
  50. }

经过如上配置后,运行出现如下异常:

  1. Hibernate: insert into test.person (name, age, pid) values (?, ?, ?)
  2. Hibernate: update test.address set p_id=? where aid=?
  3. log4j:WARN No appenders could be found for logger (org.hibernate.cfg.Environment).
  4. log4j:WARN Please initialize the log4j system properly.
  5. Exception in thread "main" org.hibernate.TransientObjectException: object references an unsaved transient instance - save the transient instance before flushing: org.wsj.oneTOmanyHibernateDemo.pojo.Address
  6.  at org.hibernate.engine.ForeignKeys.getEntityIdentifierIfNotUnsaved(ForeignKeys.java:219)
  7.  at org.hibernate.type.EntityType.getIdentifier(EntityType.java:397)
  8.  at org.hibernate.type.ManyToOneType.nullSafeSet(ManyToOneType.java:78)
  9.  at org.hibernate.persister.collection.AbstractCollectionPersister.writeElement(AbstractCollectionPersister.java:755)
  10.  at org.hibernate.persister.collection.AbstractCollectionPersister.recreate(AbstractCollectionPersister.java:1143)
  11.  at org.hibernate.action.CollectionRecreateAction.execute(CollectionRecreateAction.java:26)
  12.  at org.hibernate.engine.ActionQueue.execute(ActionQueue.java:250)
  13.  at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:234)
  14.  at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:145)
  15.  at org.hibernate.event.def.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:298)
  16.  at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:27)
  17.  at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:1000)
  18.  at org.hibernate.impl.SessionImpl.managedFlush(SessionImpl.java:338)
  19.  at org.hibernate.transaction.JDBCTransaction.commit(JDBCTransaction.java:106)
  20.  at org.wsj.oneTOmanyHibernateDemo.operator.PersonAdressOperator.add(PersonAdressOperator.java:23)
  21.  at org.wsj.oneTOmanyHibernateDemo.operator.PersonAdressOperator.main(PersonAdressOperator.java:55)

如上异常的解决方法为:

原因:

     由于Person.hbm.xml文件设置的关系为person为主控类(关系有他来维护)且cascade="none"不使用级联关系。

     根据上述的SQL描述:

                Hibernate: insert into test.person (name, age, pid) values (?, ?, ?)

                Hibernate: update test.address set p_id=? where aid=? 

            

        『  

            应该是程序试图保存一个被清空的对象:org.wsj.oneTOmanyHibernateDemo.pojo.Address。

            这里的cascade=none就是说他只能保存一个Person对象,但是inverse="false"则表示由Person维护关系,

           也就是说Person尝试控制Address,而cascade在保存Person时就将Address剔除了,所以这里出现了

            

            应该是程序试图保存一个被清空的对象的异常。 即:    

            (save the transient instance before flushing: org.wsj.oneTOmanyHibernateDemo.pojo.Address)。

 

           如果将inverse="true",则Person不在维护关系,不会控制Address(不会尝试保存Address了)便不会出现了如上异常了。

           或者将cascade="all",则Address不会被剔除,也就是说Person的控制Address仍然存在。也不会出现上述异常。

        』

        如上分析是本人,自己的个人分析,有待进一步考证

 

修改Person.hbm.xml :

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
  3. "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
  4. <!-- 
  5.     Mapping file autogenerated by MyEclipse Persistence Tools
  6. -->
  7. <hibernate-mapping>
  8.     <class name="org.wsj.oneTOmanyHibernateDemo.pojo.Person" table="person" catalog="test">
  9.         <id name="pid" type="string">
  10.             <column name="pid" length="32" />
  11.             <generator class="uuid.hex" />
  12.         </id>
  13.         <property name="name" type="string">
  14.             <column name="name" length="20" not-null="true" />
  15.         </property>
  16.         <property name="age" type="integer">
  17.             <column name="age" not-null="true" />
  18.         </property>
  19.         <property name="nowdate" type="date" insert="false">
  20.             <column name="nowdate" length="10" not-null="true" />
  21.         </property>
  22.         
  23.         <set name="address" table="address" cascade="all" inverse="true">
  24.          <key column="p_id"/>
  25.          <one-to-many class="org.wsj.oneTOmanyHibernateDemo.pojo.Address"/>
  26.         </set>
  27.     </class>
  28. </hibernate-mapping>

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值