hibernate双向一对多关联

本文探讨了hibernate中双向一对多关联的实现,并通过测试脚本展示了如何在一的一方和多的一方进行维护。通常推荐在多的一方维护关联关系,以避免额外的更新操作。
摘要由CSDN通过智能技术生成

测试脚本:

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多方的外键

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值