Hibernate中inverse="true"的理解


举例如下  

Customer类:  
Java代码    收藏代码
  1. public class Customer {   
  2.     private int id;   
  3.     private String name;  
  4. private Set orders = new HashSet();  
  5. •••  
  6. }  

即Customer类具有一个set集合属性orders,其中Order是一个普通的类:  
Java代码    收藏代码
  1. public class Order {   
  2.     private int id;   
  3.     private String orderName;  
  4. •••  
  5. }  

数据库中表的结构:  
Java代码    收藏代码
  1. t_customer:  两个字段:id  name  
  2. t_order:     三个字段:id  orderName  customerid  


Customer类的映射文件:Customer.hbm.xml  (Order类的映射文件忽略)  
Java代码    收藏代码
  1. <hibernate-mapping>  
  2.     <class name="test.Customer" table="t_customer" lazy="false">    
  3.         <id name="id">   
  4.            <generator class="native"/>  
  5.         </id>    
  6.         <property name="name"/>    
  7.         <set name="orders"  cascade="save-update"  lazy="false">  
  8.            <key column="customerid"/>  
  9.            <one-to-many class="test.Order"/>  
  10.         </set>  
  11.     </class>   
  12. </hibernate-mapping>  

执行如下代码:  
Java代码    收藏代码
  1. Set orders = new HashSet();   
  2.               
  3. Order o1 = new Order();  
  4. o1.setOrderName("o1");   
  5. Order o2 = new Order();  
  6. o2.setOrderName("o2");     
  7. orders.add(o1);  
  8. orders.add(o2);       
  9.               
  10. Customer c = new Customer();  
  11. c.setName("aaa");  
  12. c.setOrders(orders);    
  13.   
  14. session.save(c);   

此时Hibernate发出的sql语句如下:  
Java代码    收藏代码
  1. Hibernate: insert into t_customer (name) values (?)  
  2. Hibernate: insert into t_order (orderName) values (?)  
  3. Hibernate: insert into t_order (orderName) values (?)  
  4. Hibernate: update t_order set customerid=? where id=?  
  5. Hibernate: update t_order set customerid=? where id=?  

查看数据库:  
Java代码    收藏代码
  1. t_customer :                    t_order:     
  2.   
  3. id   |  name                   id   |   orderName   |   customerid   
  4. 1       aaa                    1           o1              1  
  5.                                2           o2              1   

保存Customer对象时,首先发出insert into t_customer (name) values (?)语句将c同步到数据库,由于在<set>映射中设置cascade="save-update",所以会同时保存orders集合中的Order类型的o1,o2对象(如果没有这个设置,即cascade="save-update"),那么Hibenrate不会自动保存orders集合中的对象,那么在更新时将会抛出如下异常:  
Java代码    收藏代码
  1. Hibernate: insert into t_customer (name) values (?)  
  2. Hibernate: update t_order set customerid=? where id=?  
  3. org.hibernate.TransientObjectException: test.Order  
  4. ••••••  

抛出这一异常的原因是:<set>映射默认"inverse=fasle"即由Customer对象作为主控方,那么它要负责关联的维护工作,在这里也就是负责更新t_order表中的customerid字段的值,但由于未设置cascade="save-update",所以orders集合中的对象不会在保存customer时自动保存,因此会抛出异常(如果未设置,需要手动保存)。  
现在设置cascade="save-update",同时设置inverse="true",即:  
Java代码    收藏代码
  1. •••  
  2. <set name="orders" cascade="save-update" inverse="true" lazy="false">  
  3.     <key column="customerid"/>  
  4.     <one-to-many class="test.Order"/>  
  5. </set>    
  6. •••  

同样执行上述代码,发出如下语句:  
Java代码    收藏代码
  1. Hibernate: insert into t_customer (name) values (?)  
  2. Hibernate: insert into t_order (orderName) values (?)  
  3. Hibernate: insert into t_order (orderName) values (?)  

相比上一次执行,少了两条update语句,查看数据库:  
Java代码    收藏代码
  1. t_customer :                    t_order:     
  2.   
  3. id   |  name                   id   |   orderName   |   customerid   
  4. 1       aaa                    1           o1              NULL  
  5.                                2           o2              NULL  

发现t_order表中customerid的值为NULL,这是由于设置了inverse="true",它意味着  
Customer不再作为主控方,而将关联关系的维护工作交给关联对象Orders来完成。在保存Customer时,Customer不在关心Orders的customerid属性,必须由Order自己去维护,即设置order.setCustomer(customer);  

如果需要通过Order来维护关联关系,那么这个关联关系转换成双向关联。  
修改Order类代码:  
Java代码    收藏代码
  1. public class Order {   
  2.     private int id;   
  3.     private String orderName;    
  4.     private Customer customer;  
  5. •••  
  6. }  

Order.hbm.xml:  
Java代码    收藏代码
  1. <hibernate-mapping>  
  2.     <class name="test.Order" table="t_order">    
  3.         <id name="id">   
  4.            <generator class="native"/>  
  5.         </id>    
  6.         <property name="orderName"/>     
  7.         <many-to-one name="customer" column="customerid"/>   
  8.     </class>   
  9. </hibernate-mapping>  

此时数据库中表的结构不会变化。  

再次执行上述代码,发出如下sql语句:  
Java代码    收藏代码
  1. Hibernate: insert into t_customer (name) values (?)  
  2. Hibernate: insert into t_order (orderName, customerid) values (?, ?)  
  3. Hibernate: insert into t_order (orderName, customerid) values (?, ?)   

发现在保存Order对象时为customerid字段赋值,因为Order对象中拥有Customer属性,对应customerid字段,查看数据库表:  
Java代码    收藏代码
  1. t_customer :                    t_order:     
  2.   
  3. id   |  name                   id   |   orderName   |   customerid   
  4. 1       aaa                    1           o1              NULL  
  5.                                2           o2              NULL  

发现customerid的值仍为NULL,因为在上述代码中并未设置Order对象的Customer属性值,由于设置了inverse="true",所以Order对象需要维护关联关系,所以必须进行设置,即  
order.setCustomer(customer);  

修改上述代码为:  
Java代码    收藏代码
  1. •••  
  2. Customer c = new Customer();  
  3.               
  4. Set orders = new HashSet();   
  5. Order o1 = new Order();  
  6. o1.setOrderName("o1");   
  7. o1.setCustomer(c);  
  8. Order o2 = new Order();  
  9. o2.setOrderName("o2");  
  10. o2.setCustomer(c);  
  11. orders.add(o1);  
  12. orders.add(o2);       
  13.               
  14. c.setName("aaa");  
  15. c.setOrders(orders);   
  16.               
  17. session.save(c);   
  18. •••   
  19.    

执行上述代码,发出如下语句:  
Java代码    收藏代码
  1. Hibernate: insert into t_customer (name) values (?)  
  2. Hibernate: insert into t_order (orderName, customerid) values (?, ?)  
  3. Hibernate: insert into t_order (orderName, customerid) values (?, ?)  

查看数据库:  
Java代码    收藏代码
  1. t_customer :                    t_order:     
  2.   
  3. id   |  name                   id   |   orderName   |   customerid   
  4. 1       aaa                    1           o1              1  
  5.                                2           o2              1  

发现已经设置了customerid的值。  

在一对多关联中,在多的一方设置inverse="true",有助于性能的改善。通过上述分析可以发现少了update语句。  
width="468" height="60" src="http://lijiejava.iteye.com/iframe_ggbd/187" frameborder="0" scrolling="no" style="font: 12px/18px Helvetica, Tahoma, Arial, sans-serif; text-align: left; color: rgb(0, 0, 0); text-transform: none; text-indent: 0px; letter-spacing: normal; word-spacing: 0px; white-space: normal; -webkit-text-stroke-width: 0px;">
分享到:    
评论
7 楼   u010214546  2015-05-22  
握着橄榄枝的人 写道
在一对多关联中,在多的一方设置inverse="true",有助于性能的改善。通过上述分析可以发现少了update语句。 这句话说错了吧,是在一对多的关联中,在1的一方设置inverse="true",让多的一方来维护关系,我看你也是这么做的啊,你不是在1的一方设置这个inverse="true",然后少了更新语句吗。

我也同意你的说法,我觉得是博主笔误了。
6 楼   握着橄榄枝的人  2014-01-16  
在一对多关联中,在多的一方设置inverse="true",有助于性能的改善。通过上述分析可以发现少了update语句。 这句话说错了吧,是在一对多的关联中,在1的一方设置inverse="true",让多的一方来维护关系,我看你也是这么做的啊,你不是在1的一方设置这个inverse="true",然后少了更新语句吗。
5 楼   幕风落雨  2013-08-13  
很全面详细
4 楼   yangyingcan2012  2013-06-19  
 讲得比较好,学习了
3 楼   feipigzi  2012-07-19  
w156445045 写道
目前SSH项目中都是这么做的,问下是不是实际的项目中都是这种多对多的关联关系呢?
我用myeclipse的逆向生成的代码也是这种多对多的,
<set name="enterprisePowers" inverse="true" cascade="all">
            <key>
                <column name="eno" precision="18" scale="0" not-null="true" />
            </key>
            <one-to-many class="com.yaxing.pojo.EnterprisePower" />
        </set>
cascade 这个是自己加的~

以上说的是一对多的关系
2 楼   w156445045  2011-12-30  
上面写错了,是双向关系,是不是都建立的这种双向的关系呢?  

不是说多对一才是最适合关系数据库的外键的吗?
1 楼   w156445045  2011-12-30  
目前SSH项目中都是这么做的,问下是不是实际的项目中都是这种多对多的关联关系呢?  
我用myeclipse的逆向生成的代码也是这种多对多的,  
<set name="enterprisePowers" inverse="true" cascade="all">  
            <key>  
                <column name="eno" precision="18" scale="0" not-null="true" />  
            </key>  
            <one-to-many class="com.yaxing.pojo.EnterprisePower" />  
        </set>  
cascade 这个是自己加的~

以下是对提供的参考资料的总结,按照要求结构化多个要点分条输出: 4G/5G无线网络优化与网规案例分析: NSA站点下终端掉4G问题:部分用户反馈NSA终端频繁掉4G,主要因终端主动发起SCGfail导致。分析显示,在信号较好的环境下,终端可能因节能、过热保护等原因主动释放连接。解决方案建议终端侧进行分析处理,尝试关闭节电开关等。 RSSI算法识别天馈遮挡:通过计算RSSI平均值及差值识别天馈遮挡,差值大于3dB则认定有遮挡。不同设备分组规则不同,如64T和32T。此方法可有效帮助现场人员识别因环境变化引起的网络问题。 5G 160M组网小区CA不生效:某5G站点开启100M+60M CA功能后,测试发现UE无法正常使用CA功能。问题原因在于CA频点集标识配置错误,修正后测试正常。 5G网络优化与策略: CCE映射方式优化:针对诺基亚站点覆盖农村区域,通过优化CCE资源映射方式(交织、非交织),提升RRC连接建立成功率和无线接通率。非交织方式相比交织方式有显著提升。 5G AAU两扇区组网:与三扇区组网相比,AAU两扇区组网在RSRP、SINR、下载速率和上传速率上表现不同,需根据具体场景选择适合的组网方式。 5G语音解决方案:包括沿用4G语音解决方案、EPS Fallback方案和VoNR方案。不同方案适用于不同的5G组网策略,如NSA和SA,并影响语音连续性和网络覆盖。 4G网络优化与资源利用: 4G室分设备利旧:面对4G网络投资压减与资源需求矛盾,提出利旧多维度调优策略,包括资源整合、统筹调配既有资源,以满足新增需求和提质增效。 宏站RRU设备1托N射灯:针对5G深度覆盖需求,研究使用宏站AAU结合1托N射灯方案,快速便捷地开通5G站点,提升深度覆盖能力。 基站与流程管理: 爱立信LTE基站邻区添加流程:未提供具体内容,但通常涉及邻区规划、参数配置、测试验证等步骤,以确保基站间顺畅切换和覆盖连续性。 网络规划与策略: 新高铁跨海大桥覆盖方案试点:虽未提供详细内容,但可推测涉及高铁跨海大桥区域的4G/5G网络覆盖规划,需考虑信号穿透、移动性管理、网络容量等因素。 总结: 提供的参考资料涵盖了4G/5G无线网络优化、网规案例分析、网络优化策略、资源利用、基站管理等多个方面。 通过具体案例分析,展示了无线网络优化的常见问题及解决方案,如NSA终端掉4G、RSSI识别天馈遮挡、CA不生效等。 强调了5G网络优化与策略的重要性,包括CCE映射方式优化、5G语音解决方案、AAU扇区组网选择等。 提出了4G网络优化与资源利用的策略,如室分设备利旧、宏站RRU设备1托N射灯等。 基站与流程管理方面,提到了爱立信LTE基站邻区添加流程,但未给出具体细节。 新高铁跨海大桥覆盖方案试点展示了特殊场景下的网络规划需求。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值