hibernate 9 使用对象 | hibernate 实战(第二版) 第9章使用对象 | 笔记

1持久化声明周期 

对象状态: 
1、瞬时状态(新建状态)(临时状态) 
瞬时状态其实就是和持久化没啥关系,只是new出来一个类,和数据库也没啥关联,session机制也监控不到。只能等着被 
垃圾回收机制回收。 

2、持久化状态(托管状态) 
就是已经交给容器管理,肯定是已经有和数据库关联的主键。且,目前属于高速缓存状态,容器会检测到实体的数据修改。 

3、移除状态(删除状态) 
也就是被删除了,session关闭了,他也就等着回收了。 

4、脱管状态(游离状态) 
大多就是session关闭了,但是对象中还存在和数据库关联的字段。 





持久化上下文: 
作用: 
1、hibernate可以进行自动的脏检查和事务延迟写入。 
2、hibernate可以用持久化上下文作为一级高速缓存 
3、hibernate可以保证Java对象同一性范围 
4、hibernate可以把持久化上下文扩展到跨整个回话。 


org.hibernate.event.def.DefaultLoadEventListener 
440L(试图找到在session级别的缓存的实体) 
Object entity = loadFromSessionCache( event, keyToLoad, options ); 
然后还会反复寻找各种缓存机制,如果没有,就会调用 
return loadFromDatasource(event, persister, keyToLoad, options); 


2对象同一性和等同性 
对象同一性和等同性: 


扩展持久化上下文: 




3hibernate接口 

hibernate get 和 load 区别
 
引用 传智: 

相同点: 都可以通过指定的实体类与ID从数据库中读取数据,并返回对应的实例, 
不同点: 
load方法: hibernate认为该id对应的对象(数据库记录)在数据库 中是一定存在的,进而使用代理来延迟加载该对象。在用到该对象中的属性数据时才查询数据库,若查不到,则抛出 ObjectNotFoundEcception 异常.load方法抛异常是指在使用该对象的数据且数据库中不存在该数据时,而不是在创建这个对象时。由于 session 中的缓存对于hibernate来说是个较廉价的资源,所以在load 时会先查一下session缓存看看该id对应的对象是否存在,不存在则创建代理。 
get方法: hibernate会确认该id对应的数据是否存在,首先在session 缓存中查找,然后在二级缓存中查找,还没有就查数据库,数据库中没有就返回null。 


引用 in action: 
get()和load()之间的一个区别在于他们如何表明实例无法被找到。如果数据库中不存在包含给定标示符的行,get()就会返回null。load()方法则抛出一个 
ObjectNotFoundException。由你选择喜欢的错误处理方式。 
更重要的是,load()方法可能返回一个代理(proxy),一个占位符,而不是命中(hit)数据库。这个结果就是稍后你可能得到一个ObjectNotFoundException, 
一旦你试图访问返回的占位符,就立即强制它初始化。(这也称作延迟加载(lazy loading))load()方法始终试图返回一个代理,如果它已经由当前的持久化上下文管理,则返回一个已经初始化的对象实例。get()方法从不返回代理,它始终命中数据库。 






merge:作用
  1.     private static void merge1() {  
  2.         Configuration configuration = new Configuration().configure();  
  3.         SessionFactory sessionFactory = configuration.buildSessionFactory();  
  4.         Session session1 = sessionFactory.openSession();  
  5.         Transaction tr1 = session1.beginTransaction();  
  6.           
  7.         TestBean testBean1 = (TestBean) session1.get(TestBean.class1);  
  8.           
  9.         tr1.commit();  
  10.         session1.close();  
  11.           
  12.         testBean1.setPassword("234");  
  13.           
  14.           
  15.         Session session2 = sessionFactory.openSession();  
  16.         Transaction tr2 = session2.beginTransaction();  
  17.           
  18.         TestBean testBean2 = (TestBean) session2.get(TestBean.class1);  
  19.         testBean2.setName("hello2");  
  20.         testBean2.setPassword("456");  
  21.           
  22.         //执行update会报错:  
  23.         //org.hibernate.NonUniqueObjectException: a different object with the same identifier value was already associated with the session  
  24.         session2.update(testBean1);  
  25.           
  26.         tr2.commit();  
  27.         session2.close();  
  28.           
  29.         sessionFactory.close();  
  30.     }  
  31.       
  32.       
  33.       
  34.     private static void merge2() {  
  35.         Configuration configuration = new Configuration().configure();  
  36.         SessionFactory sessionFactory = configuration.buildSessionFactory();  
  37.         Session session1 = sessionFactory.openSession();  
  38.         Transaction tr1 = session1.beginTransaction();  
  39.           
  40.         TestBean testBean1 = (TestBean) session1.get(TestBean.class1);  
  41.           
  42.         tr1.commit();  
  43.         session1.close();  
  44.           
  45.         testBean1.setPassword("234");  
  46.           
  47.           
  48.         Session session2 = sessionFactory.openSession();  
  49.         Transaction tr2 = session2.beginTransaction();  
  50.           
  51.         TestBean testBean2 = (TestBean) session2.get(TestBean.class1);  
  52.         testBean2.setName("hello2");  
  53.         testBean2.setPassword("456");  
  54.           
  55.         TestBean testBean3 = (TestBean)session2.merge(testBean1);  
  56.           
  57.         System.out.println(testBean1);  
  58.         System.out.println(testBean2);  
  59.         System.out.println(testBean3);  
  60.           
  61. //      打印如下(testBean2的hello2的name属性改变被覆盖了):  
  62. //      TestBean [id=1, name=hello, password=234]  
  63. //      TestBean [id=1, name=hello, password=234]  
  64. //      TestBean [id=1, name=hello, password=234]  
  65.           
  66. //      Hibernate: update Test_Bean set name=?, password=? where id=?  
  67.           
  68.         tr2.commit();  
  69.         session2.close();  
  70.           
  71.         sessionFactory.close();  
  72.     }  




session.setFlushMode() 






4JPA
 

删除区别: 
在hibernate中,下面的方法是ok的
  1.   private static void delete() {  
  2. Configuration configuration = new Configuration().configure();  
  3. SessionFactory sessionFactory = configuration.buildSessionFactory();  
  4. Session session = sessionFactory.openSession();  
  5. Transaction tr = session.beginTransaction();  
  6.   
  7. TestBean testBean = new TestBean();  
  8. testBean.setId(1);  
  9.   
  10. session.delete(testBean);  
  11.   
  12. tr.commit();  
  13. session.close();  
  14.   
  15. sessionFactory.close();  

在JPA中:
  1.    private static void delete() {  
  2.     EntityManagerFactory factory = Persistence.createEntityManagerFactory("partner4java");  
  3.     EntityManager em = factory.createEntityManager();  
  4.     EntityTransaction tr = em.getTransaction();  
  5.     tr.begin();  
  6.       
  7.     TestBean testBean = new TestBean();  
  8.     testBean.setId(1);  
  9.       
  10.     //报错(不能一个托管在状态的实体调用remove):Removing a detached instance  
  11.     em.remove(testBean);  
  12.       
  13.     tr.commit();  
  14.     em.close();  
  15.     factory.close();  
  16. }  

应该:
  1. private static void delete2() {  
  2.     EntityManagerFactory factory = Persistence.createEntityManagerFactory("partner4java");  
  3.     EntityManager em = factory.createEntityManager();  
  4.     EntityTransaction tr = em.getTransaction();  
  5.     tr.begin();  
  6.       
  7.     em.remove(em.getReference(TestBean.class2));  
  8.       
  9.     tr.commit();  
  10.     em.close();  
  11.     factory.close();  
  12. }  



单独实例的清除?hibernate利用evict(object),jpa不存在这种规范。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值