关于hibernate实现的set类问题
2013-05-07 12:43
453 查看
hibernate自实现的set类如persiterSet,在hibernate有很大的用处:
用例1:
当执行saveOrUpdate()的时候不会发出任何语句。
当执行saveOrUpdate的时候只会发出一条更新customer的语句(上一条语句的更正)。
但是下面案例就不一样了:
发出语句:
为什么会出现这样的情况呢?
其实这就是Hibernate自实现set的功能,这里仅仅是set的它的一个作用哦!
persiterSet中有个init即初始化标记,在案例1中由于没有初始化该set,因此在更新游离态的时候,Hibernate发现set中的初始化标记为false,即没初始化,那么此时hiberante会认定该customer中的set集合没有发生改变,更不会发出update order null.
如果显式的使用Hibernate.initialize(customer.getOrders());,那么会更新初始化标记,为true,那么执行saveOrUpdate的时候,就无法判断customer中的set集合中的orders有没有改变,因此会发出好多条Update order 语句。
下面还有一个比较好的例子,不能说是奇葩,只能说hibernate的延迟机制吧
如果改为Load(customer),那么这个时候由于返回的是代理对象,那么Hibernate就一定能知道该代理对象是否被改变过,因为hibernate知道该代理对象到底有没有初始化!那么当执行saveOrUpdate()的时候不会发出update order set.......即更新orader的语句。
但是在delete操作的时候就会发现问题:
delete(customer),的时候如果customer这一端set没有设置级联,但是可以控制customer与order的关系:
Customer customer = (Customer)session.get(Customer.class, 13);
session.delete(customer);
这个时候会先发一条update order set cutomer_id=null,然后再发出delete cutomer
说明Hibernate在删除的时候会认为order集合为空存在脏数据(这句话是错误的,不是存在脏数据才update,而是因为customer必须控制关系),而customer控制了关系,因此会update order null,这与上面的案例不太符合。应该是hibernate在delete操作
的时候认为set为空的时候是改变过的吧。
但是如果:
显式的加载orders集合,Hibernate.initialize(orders);,那么这个时候删除的时候就会报错:
org.hibernate.ObjectDeletedException: deleted object would be re-saved by cascade
其实 我觉得Hibernate是这样做的,hibernate中的perisiterset有个dirty属性,当改变set的时候会改变更新dirty为true,而此时没有改变,因此不会发出update.
在删除一个对象的时候,因为不存在级联删除,因此会报上面的错,因此删除之前必须先清除customer和order的关系才行,即cutomer.getOrders().remove(orders)
当然delete操作的原理与上面saveOrUpdate()机制是不一样的,目前只能这么想了。。
用例1:
public void test5() { Session session = HibernateUtil.getInstance().getSession(); Transaction tx = null; tx = session.beginTransaction(); Customer customer=null; try { //延迟加载下的customer是存在session中的 customer = (Customer)session.get(Customer.class, 7); tx.commit(); }catch(Exception e) { tx.rollback(); e.printStackTrace(); }finally { session.close(); } Session session1 = HibernateUtil.getInstance().getSession(); Transaction tx1 = null; tx1 = session1.beginTransaction(); try { session1.saveOrUpdate(customer); tx1.commit(); }catch(Exception e) { tx1.rollback(); e.printStackTrace(); }finally { session1.close(); } }
当执行saveOrUpdate()的时候不会发出任何语句。
当执行saveOrUpdate的时候只会发出一条更新customer的语句(上一条语句的更正)。
但是下面案例就不一样了:
public void test5() { Session session = HibernateUtil.getInstance().getSession(); Transaction tx = null; tx = session.beginTransaction(); Customer customer=null; try { //延迟加载下的customer是存在session中的 customer = (Customer)session.get(Customer.class, 11); Hibernate.initialize(customer.getOrders()); tx.commit(); }catch(Exception e) { tx.rollback(); e.printStackTrace(); }finally { session.close(); } Session session1 = HibernateUtil.getInstance().getSession(); Transaction tx1 = null; tx1 = session1.beginTransaction(); try { session1.saveOrUpdate(customer); tx1.commit(); }catch(Exception e) { tx1.rollback(); e.printStackTrace(); }finally { session1.close(); } }
发出语句:
Hibernate: update t_customer set name=? where customer_id=? Hibernate: update t_order set order_num=?, customer_id=? where order_id=? Hibernate: update t_order set order_num=?, customer_id=? where order_id=? Hibernate: update t_order set order_num=?, customer_id=? where order_id=? Hibernate: update t_order set order_num=?, customer_id=? where order_id=? Hibernate: update t_order set order_num=?, customer_id=? where order_id=? Hibernate: update t_order set order_num=?, customer_id=? where order_id=?
为什么会出现这样的情况呢?
其实这就是Hibernate自实现set的功能,这里仅仅是set的它的一个作用哦!
persiterSet中有个init即初始化标记,在案例1中由于没有初始化该set,因此在更新游离态的时候,Hibernate发现set中的初始化标记为false,即没初始化,那么此时hiberante会认定该customer中的set集合没有发生改变,更不会发出update order null.
如果显式的使用Hibernate.initialize(customer.getOrders());,那么会更新初始化标记,为true,那么执行saveOrUpdate的时候,就无法判断customer中的set集合中的orders有没有改变,因此会发出好多条Update order 语句。
下面还有一个比较好的例子,不能说是奇葩,只能说hibernate的延迟机制吧
public void test5() { Session session = HibernateUtil.getInstance().getSession(); Transaction tx = null; tx = session.beginTransaction(); Customer customer=null; try { //延迟加载下的customer是存在session中的 customer = (Customer)session.load(Customer.class, 7); tx.commit(); }catch(Exception e) { tx.rollback(); e.printStackTrace(); }finally { session.close(); } Session session1 = HibernateUtil.getInstance().getSession(); Transaction tx1 = null; tx1 = session1.beginTransaction(); try { session1.saveOrUpdate(customer); tx1.commit(); }catch(Exception e) { tx1.rollback(); e.printStackTrace(); }finally { session1.close(); } }
如果改为Load(customer),那么这个时候由于返回的是代理对象,那么Hibernate就一定能知道该代理对象是否被改变过,因为hibernate知道该代理对象到底有没有初始化!那么当执行saveOrUpdate()的时候不会发出update order set.......即更新orader的语句。
但是在delete操作的时候就会发现问题:
delete(customer),的时候如果customer这一端set没有设置级联,但是可以控制customer与order的关系:
Customer customer = (Customer)session.get(Customer.class, 13);
session.delete(customer);
这个时候会先发一条update order set cutomer_id=null,然后再发出delete cutomer
说明Hibernate在删除的时候会认为order集合为空存在脏数据(这句话是错误的,不是存在脏数据才update,而是因为customer必须控制关系),而customer控制了关系,因此会update order null,这与上面的案例不太符合。应该是hibernate在delete操作
的时候认为set为空的时候是改变过的吧。
但是如果:
显式的加载orders集合,Hibernate.initialize(orders);,那么这个时候删除的时候就会报错:
org.hibernate.ObjectDeletedException: deleted object would be re-saved by cascade
其实 我觉得Hibernate是这样做的,hibernate中的perisiterset有个dirty属性,当改变set的时候会改变更新dirty为true,而此时没有改变,因此不会发出update.
在删除一个对象的时候,因为不存在级联删除,因此会报上面的错,因此删除之前必须先清除customer和order的关系才行,即cutomer.getOrders().remove(orders)
当然delete操作的原理与上面saveOrUpdate()机制是不一样的,目前只能这么想了。。
相关文章推荐
- 关于Hibernate实现继承树的问题
- 关于Spring+Hibernate注解式整合问题
- 关于spring+hibernate整合的一些问题
- 关于Session的机制,实现方式和安全、单点故障问题
- cannot modify header information 关于实现widget页面跳转的问题
- 关于jforum2.1.6的检索问题(采用lucene实现)
- 编码问题 关于hibernate jdbc数据库连接在xml配置与在properties文件配置的差异
- 【经典算法】:关于硬币称重问题及编程实现
- 关于使用Hibernate注解的时候遇到的问题
- 关于主域与额外域实现负载均衡及优先级登陆问题
- Spring3.0 JPA(hibernate3.6实现)整合问题之:java.lang.NoSuchMethodError: javax.persistence.spi.PersistenceUni
- 关于Spring整合Hibernate中自动建表问题(hbm2ddl.auto)
- 3月题外:关于JS实现图片缩略图效果的一个小问题
- 关于No Dialect mapping for JDBC type :-9 hibernate执行原生sql语句问题
- 关于hibernate中文写入mysql数据库乱码问题
- 关于hibernate+mysql中文乱码的问题
- 【hibernate】关于org.hibernate.ObjectNotFoundException: No row with the given identifier exists 的快捷解决问题
- 关于Ceph的EC实现rollback的两个问题
- 关于如何在java中实现中文首字母索引排序的问题
- 一道关于孩子分糖的问题!!循环链表实现