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文件:
- <?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">
- <!--
- Mapping file autogenerated by MyEclipse Persistence Tools
- -->
- <hibernate-mapping>
- <class name="org.wsj.oneTOmanyHibernateDemo.pojo.Person" table="person" catalog="test">
- <id name="pid" type="string">
- <column name="pid" length="32" />
- <generator class="uuid.hex" />
- </id>
- <property name="name" type="string">
- <column name="name" length="20" not-null="true" />
- </property>
- <property name="age" type="integer">
- <column name="age" not-null="true" />
- </property>
- <property name="nowdate" type="date" insert="false">
- <column name="nowdate" length="10" not-null="true" />
- </property>
- <set name="address" table="address" cascade="all" inverse="true">
- <key column="p_id"/>
- <one-to-many class="org.wsj.oneTOmanyHibernateDemo.pojo.Address"/>
- </set>
- </class>
- </hibernate-mapping>
Address.hbm.xml文件:
- <?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">
- <!--
- Mapping file autogenerated by MyEclipse Persistence Tools
- -->
- <hibernate-mapping>
- <class name="org.wsj.oneTOmanyHibernateDemo.pojo.Address"
- table="address" catalog="test">
- <id name="aid" type="string">
- <column name="aid" length="32" />
- <generator class="uuid.hex"></generator>
- </id>
- <property name="name" type="string">
- <column name="name" length="20" not-null="true" />
- </property>
- <property name="descirable" type="string">
- <column name="descirable" length="100" not-null="true" />
- </property>
- <many-to-one name="person"
- class="org.wsj.oneTOmanyHibernateDemo.pojo.Person">
- <column name="p_id" />
- </many-to-one>
- </class>
- </hibernate-mapping>
PersonAdressOperator .java文件:
- package org.wsj.oneTOmanyHibernateDemo.operator;
- import java.util.HashSet;
- import org.hibernate.Session;
- import org.hibernate.cfg.Configuration;
- import org.wsj.oneTOmanyHibernateDemo.pojo.Address;
- import org.wsj.oneTOmanyHibernateDemo.pojo.Person;
- public class PersonAdressOperator {
- private Session session;
- public PersonAdressOperator() {
- this.session = new Configuration().configure().buildSessionFactory()
- .openSession();
- }
- public void add(Person p) {
- this.session.save(p);
- this.session.beginTransaction().commit();
- }
- public static void main(String[] args) {
- PersonAdressOperator po = new PersonAdressOperator();
- Person p = new Person();
- p.setName("scofield_alex");
- p.setAge(1);
- p.setAddress(new HashSet<Address>());
- Address ad = null;
- ad = new Address();
- ad.setName("朝阳区");
- ad.setDescirable("朝阳新区");
- ad.setPerson(p);
- p.getAddress().add(ad);
- //
- // ad = new Address();
- // ad.setName("海淀区");
- // ad.setDescirable("海淀新区");
- // ad.setPerson(p);
- // p.getAddress().add(ad);
- //
- // ad = new Address();
- // ad.setName("天安门广场");
- // ad.setDescirable("天安门广场");
- // ad.setPerson(p);
- // p.getAddress().add(ad);
- po.add(p);
- }
- }
经过如上配置后,运行出现如下异常:
- Hibernate: insert into test.person (name, age, pid) values (?, ?, ?)
- Hibernate: update test.address set p_id=? where aid=?
- log4j:WARN No appenders could be found for logger (org.hibernate.cfg.Environment).
- log4j:WARN Please initialize the log4j system properly.
- Exception in thread "main" org.hibernate.TransientObjectException: object references an unsaved transient instance - save the transient instance before flushing: org.wsj.oneTOmanyHibernateDemo.pojo.Address
- at org.hibernate.engine.ForeignKeys.getEntityIdentifierIfNotUnsaved(ForeignKeys.java:219)
- at org.hibernate.type.EntityType.getIdentifier(EntityType.java:397)
- at org.hibernate.type.ManyToOneType.nullSafeSet(ManyToOneType.java:78)
- at org.hibernate.persister.collection.AbstractCollectionPersister.writeElement(AbstractCollectionPersister.java:755)
- at org.hibernate.persister.collection.AbstractCollectionPersister.recreate(AbstractCollectionPersister.java:1143)
- at org.hibernate.action.CollectionRecreateAction.execute(CollectionRecreateAction.java:26)
- at org.hibernate.engine.ActionQueue.execute(ActionQueue.java:250)
- at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:234)
- at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:145)
- at org.hibernate.event.def.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:298)
- at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:27)
- at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:1000)
- at org.hibernate.impl.SessionImpl.managedFlush(SessionImpl.java:338)
- at org.hibernate.transaction.JDBCTransaction.commit(JDBCTransaction.java:106)
- at org.wsj.oneTOmanyHibernateDemo.operator.PersonAdressOperator.add(PersonAdressOperator.java:23)
- 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 :
- <?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">
- <!--
- Mapping file autogenerated by MyEclipse Persistence Tools
- -->
- <hibernate-mapping>
- <class name="org.wsj.oneTOmanyHibernateDemo.pojo.Person" table="person" catalog="test">
- <id name="pid" type="string">
- <column name="pid" length="32" />
- <generator class="uuid.hex" />
- </id>
- <property name="name" type="string">
- <column name="name" length="20" not-null="true" />
- </property>
- <property name="age" type="integer">
- <column name="age" not-null="true" />
- </property>
- <property name="nowdate" type="date" insert="false">
- <column name="nowdate" length="10" not-null="true" />
- </property>
- <set name="address" table="address" cascade="all" inverse="true">
- <key column="p_id"/>
- <one-to-many class="org.wsj.oneTOmanyHibernateDemo.pojo.Address"/>
- </set>
- </class>
- </hibernate-mapping>