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:作用
session.setFlushMode()
4JPA
删除区别:
在hibernate中,下面的方法是ok的
在JPA中:
应该:
单独实例的清除?hibernate利用evict(object),jpa不存在这种规范。
对象状态:
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:作用
- private static void merge1() {
- Configuration configuration = new Configuration().configure();
- SessionFactory sessionFactory = configuration.buildSessionFactory();
- Session session1 = sessionFactory.openSession();
- Transaction tr1 = session1.beginTransaction();
- TestBean testBean1 = (TestBean) session1.get(TestBean.class, 1);
- tr1.commit();
- session1.close();
- testBean1.setPassword("234");
- Session session2 = sessionFactory.openSession();
- Transaction tr2 = session2.beginTransaction();
- TestBean testBean2 = (TestBean) session2.get(TestBean.class, 1);
- testBean2.setName("hello2");
- testBean2.setPassword("456");
- //执行update会报错:
- //org.hibernate.NonUniqueObjectException: a different object with the same identifier value was already associated with the session
- session2.update(testBean1);
- tr2.commit();
- session2.close();
- sessionFactory.close();
- }
- private static void merge2() {
- Configuration configuration = new Configuration().configure();
- SessionFactory sessionFactory = configuration.buildSessionFactory();
- Session session1 = sessionFactory.openSession();
- Transaction tr1 = session1.beginTransaction();
- TestBean testBean1 = (TestBean) session1.get(TestBean.class, 1);
- tr1.commit();
- session1.close();
- testBean1.setPassword("234");
- Session session2 = sessionFactory.openSession();
- Transaction tr2 = session2.beginTransaction();
- TestBean testBean2 = (TestBean) session2.get(TestBean.class, 1);
- testBean2.setName("hello2");
- testBean2.setPassword("456");
- TestBean testBean3 = (TestBean)session2.merge(testBean1);
- System.out.println(testBean1);
- System.out.println(testBean2);
- System.out.println(testBean3);
- // 打印如下(testBean2的hello2的name属性改变被覆盖了):
- // TestBean [id=1, name=hello, password=234]
- // TestBean [id=1, name=hello, password=234]
- // TestBean [id=1, name=hello, password=234]
- // Hibernate: update Test_Bean set name=?, password=? where id=?
- tr2.commit();
- session2.close();
- sessionFactory.close();
- }
session.setFlushMode()
4JPA
删除区别:
在hibernate中,下面的方法是ok的
- private static void delete() {
- Configuration configuration = new Configuration().configure();
- SessionFactory sessionFactory = configuration.buildSessionFactory();
- Session session = sessionFactory.openSession();
- Transaction tr = session.beginTransaction();
- TestBean testBean = new TestBean();
- testBean.setId(1);
- session.delete(testBean);
- tr.commit();
- session.close();
- sessionFactory.close();
在JPA中:
- private static void delete() {
- EntityManagerFactory factory = Persistence.createEntityManagerFactory("partner4java");
- EntityManager em = factory.createEntityManager();
- EntityTransaction tr = em.getTransaction();
- tr.begin();
- TestBean testBean = new TestBean();
- testBean.setId(1);
- //报错(不能一个托管在状态的实体调用remove):Removing a detached instance
- em.remove(testBean);
- tr.commit();
- em.close();
- factory.close();
- }
应该:
- private static void delete2() {
- EntityManagerFactory factory = Persistence.createEntityManagerFactory("partner4java");
- EntityManager em = factory.createEntityManager();
- EntityTransaction tr = em.getTransaction();
- tr.begin();
- em.remove(em.getReference(TestBean.class, 2));
- tr.commit();
- em.close();
- factory.close();
- }
单独实例的清除?hibernate利用evict(object),jpa不存在这种规范。