hibernate双向一对多关联

来源:互联网 发布:ubuntu tty 编辑:程序博客网 时间:2024/05/01 02:47

测试脚本:

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 statement00: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 statement00: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: 300:55:30,403 DEBUG Expectations:77 - success of batch update unknown: 000:55:30,405 DEBUG Expectations:77 - success of batch update unknown: 100:55:30,406 DEBUG Expectations:77 - success of batch update unknown: 200: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 statement00:55:30,412 DEBUG SQL:111 - update Person1 set addressId=? where personId=?00:55:30,412 DEBUG AbstractBatcher:248 - reusing prepared statement00:55:30,413 DEBUG SQL:111 - update Person1 set addressId=? where personId=?


在实际中,还是在多方维护较好,因为它是自己来设置的外键,没有执行上面的update操作,上面的update操作需要执行完多方insert,一方insert后,再去update多方的外键

0 0
原创粉丝点击