JPA持久化上下文与对象状态

来源:互联网 发布:台湾文献数据库 编辑:程序博客网 时间:2024/05/07 10:38


hibernate 认为一个有id的新对象为detached.

  • 自动脏检查可以通过继承org.hibernate.CustomEntityDirtinessStrategy并设置hibernate.entity_dirtiness_strategy来自定义.

JPA提供一个持久化上下文作为一级缓存,提供自动脏检查.对应某个id的实例在持久化上下文中只有一个对象.
Hibernate,find时总是尝试在当前上下文中先搜索对象,不存在再触发数据库查询.

        Test t1 = em.find(Test.class,1l);        //query执行前会先flush当前上下文,在查询数据库之后确认对象在当前会话中存在,则直接复用.        Query query = em.createQuery("from Test where test=:test");        query.setParameter("test", "fff");        Test t2 = (Test)query.getSingleResult();        //确保对象一致性,为true        System.out.println(t1 == t2);
  • persist,persist的对象不应该为detached(新创建且有id则认为是detached),用于将一个瞬时(无id)/移除对象(有id),变成持久化状态.不适合detached对象,将抛出异常.
  • merge的对象必须为detached/trasiented状态,若为removed则抛出异常.主键生成策略为assigned,则必须使用merge进行持久化.
        Test t1 = em.find(Test.class,1l);        Test t2 = new Test();        t2.setId(1l);        //不改变t1的状态,返回一个持久化对象.如果相应id的持久化对象已存在,则直接更新该对象并返回,        //否则触发数据库查询获得一个持久化对象(若查询结果为空则new创建,并根据主键生成策略决定id值),然后使用t1更新后返回        Test t3 = em.merge(t1);        //返回true,直接在已有的持久化对象上更新数据        System.out.println(t1 == t3);
  • 使用find查找对象
  • 使用getReference来懒加载对象,期间可以使用Hibernate.initialize(obj)进行数据加载,使用PersistenceUnitUtil.isLoaded(obj)来判断该代理是否初始化.
    当entityManager关闭且obj未加载时,则调用obj.attr会抛出异常.
  • 使用remove删除一个对象,对象状态变为removed,只有persist可以将其再次变为持久化对象,使用merge抛出异常.
  • 使用refresh来刷新一个对象,一般不需要
  • detach使一个对象变为托管
  • clear使得上下文所有对象变托管
  • close先执行flush再执行clear

//hibernate的一些有用方法

  • hibernate的replicate用于将一个数据合并到另一张数据表.
EntityManager emA = getDatabaseA().createEntityManager();Item item = emA.find(Item.class, ITEM_ID);EntityManager emB = getDatabaseB().createEntityManager();//IGNORE,如果id冲突则忽略.//OVERWRITE,如果id冲突则覆盖//LATEST_VERSION,使用最新数据,对于有version的乐观控制.//EXCEPTIONemB.unwrap(Session.class).replicate(item, org.hibernate.ReplicationMode.LATEST_VERSION);
  • em.unwrap(Session.class).setDefaultReadOnly(true);将上下文环境设为只读,不再检测脏数据,此时即使调用em.flush()也不会刷新
0 0
原创粉丝点击