测试脚本:
create table PERSON1
(
PERSONID NUMBER(10) not null,
ADDRESSID NUMBER(10)
)
create table ADDRESS1
(
ADDRESSID NUMBER(10) not null
)
person.hbm.xml:
<class name="com.chenjun.eshop.staffManage.domain.Person"
table="Person1">
<id name="id" column="personId">
<generator class="assigned"><!-- 由程序分配主键 -->
</generator>
</id>
<many-to-one name="address" column="addressid" not-null="true"></many-to-one>
</class>
address.hbm.xml:
<class name="com.chenjun.eshop.staffManage.domain.Address"
table="Address1">
<id name="id" column="addressId">
<generator class="assigned"><!-- 由程序分配主键 -->
</generator>
</id>
<set name="persones" inverse="true">
<key column="addressId" />
<one-to-many class="com.chenjun.eshop.staffManage.domain.Person" />
</set>
</class>
测试代码:
public void test()
{
Session session = this.getHibernateTemplate().getSessionFactory().openSession();
session.beginTransaction();
Address address = new Address();
address.setId(307);
session.save(address); //一方对象要先保存,不然在后面save时,会报找不到对象异常
Person person1 = new Person();
person1.setId(111);
person1.setAddress(address);
session.save(person1);
Person person2 = new Person();
person2.setId(222);
person2.setAddress(address);
session.save(person2);
Person person3 = new Person();
person3.setId(333);
person3.setAddress(address);
session.save(person3);
//hibernate中的增删改都要提交事件,因为它默认是设为不提交的,而jdbc的connect是默认提交的。
session.beginTransaction().commit();
//释放资源
session.close();
}
上面的代码,是在多的一方进行维护的,先insert一的一方,再insert多的一方
下面测试在一的一方来维护
sql脚本不变
<class name="com.chenjun.eshop.staffManage.domain.Address"
table="Address1">
<id name="id" column="addressId">
<generator class="assigned"><!-- 由程序分配主键 -->
</generator>
</id>
<set name="persones" inverse="false"> <!-- 这里默认的,由一端来维护关系,如果设置为true,则是由多端来维护关系 -->
<key column="addressId" />
<one-to-many class="com.chenjun.eshop.staffManage.domain.Person" />
</set>
</class>
<class name="com.chenjun.eshop.staffManage.domain.Person"
table="Person1">
<id name="id" column="personId">
<generator class="assigned"><!-- 由程序分配主键 -->
</generator>
</id>
<many-to-one name="address" column="addressid"></many-to-one>
注意上面的<many-to-one>里不要加not-null="true",这样会报错
not-null property references a null or transient value
测试代码:
public void test()
{
Session session = this.getHibernateTemplate().getSessionFactory().openSession();
session.beginTransaction();
Set<Person> persones = new HashSet<Person>();
Person person1 = new Person();
person1.setId(11112);
session.save(person1); //和在多的一方维护是一样的,都要先save,要不然,是维护不了多的一方的。
Person person2 = new Person();
person2.setId(22222);
session.save(person2);
Person person3 = new Person();
person3.setId(33332);
session.save(person3);
persones.add(person1);
persones.add(person2);
persones.add(person3);
Address address = new Address();
address.setId(401);
address.setPersones(persones);
session.save(address);
//hibernate中的增删改都要提交事件,因为它默认是设为不提交的,而jdbc的connect是默认提交的。
session.beginTransaction().commit();
//释放资源
session.close();
}
由于是一方来维护,所以先执行多方的insert,再执行一方的sql,与多方维护是相反的,注意,对一方或者多方的对象都要先save()。
后台执行如下:
00:55:30,388 DEBUG SQL:111 -<span style="background-color: rgb(204, 204, 204);"> <span style="color:#FF6666;">insert into Person1 (addressid, personId) values (?, ?)</span></span>
00:55:30,399 DEBUG AbstractBatcher:248 - reusing prepared statement
00:55:30,399 DEBUG SQL:111 -<span style="color:#FF6666;"> insert into Person1 (addressid, personId) values (?, ?)</span>
00:55:30,400 DEBUG AbstractBatcher:248 - reusing prepared statement
00:55:30,400 DEBUG SQL:111 - <span style="color:#FF6666;">insert into Person1 (addressid, personId) values (?, ?)</span>
00:55:30,401 DEBUG AbstractBatcher:66 - Executing batch size: 3
00:55:30,403 DEBUG Expectations:77 - success of batch update unknown: 0
00:55:30,405 DEBUG Expectations:77 - success of batch update unknown: 1
00:55:30,406 DEBUG Expectations:77 - success of batch update unknown: 2
00:55:30,406 DEBUG AbstractBatcher:418 - about to close PreparedStatement (open PreparedStatements: 1, globally: 1)
00:55:30,407 DEBUG AbstractBatcher:410 - about to open PreparedStatement (open PreparedStatements: 0, globally: 0)
00:55:30,407 DEBUG SQL:111 -<span style="color:#FF0000;"> insert into Address1 (addressId) values (?)
</span><pre name="code" class="java">00:55:30,411 DEBUG SQL:111 - update Person1 set addressId=? where personId=?
00:55:30,411 DEBUG AbstractBatcher:248 - reusing prepared statement
00:55:30,412 DEBUG SQL:111 - update Person1 set addressId=? where personId=?
00:55:30,412 DEBUG AbstractBatcher:248 - reusing prepared statement
00:55:30,413 DEBUG SQL:111 - update Person1 set addressId=? where personId=?
在实际中,还是在多方维护较好,因为它是自己来设置的外键,没有执行上面的update操作,上面的update操作需要执行完多方insert,一方insert后,再去update多方的外键