JPA实体状态学习-(游离态:Detached)

今天我们学习另一种实体状态,老规矩还是先上图:

Entity instance states

Detached(游离态 unmanaged)

An Object becomes detached when the currently running Persistence Context is closed. Any changes made to detached objects are no longer automatically propagated to the database.

持久化上下文关闭以后,对象就会进入游离态。任何对游离态对象的改变都不会自动持久化到数据库。

这个现象我们在上一讲已经用代码证明过,现在的问题是,由上面的图片可以看出,处于游离态的对象可以通过merge方法变成收到持久化上下文管理的持久态。我们还是用代码来说明:

public void  detachedToPersist() {
    Teacher teacher = new Teacher("new_email@gmail.com");
    logger.info("teacher: {} is transient state",teacher);
    EntityManager entityManager = entityManagerFactory.createEntityManager();
    EntityTransaction tx = entityManager.getTransaction();
    tx.begin();
    entityManager.persist(teacher);
    logger.info("teacher: {} is persistent state",teacher);
    Long persistedId = teacher.getId();
    tx.commit();
    entityManager.close();

    teacher.setEmail("update_email@gmail.com");
    logger.info("teacher: {} is detached state",teacher);

    entityManager = entityManagerFactory.createEntityManager();
    tx = entityManager.getTransaction();
    tx.begin();
    Teacher newTeacher = entityManager.merge(teacher);
    logger.info("teacher: {} is persistent state",teacher);
    persistedId = newTeacher.getId();
    tx.commit();
    entityManager.close();

    entityManager = entityManagerFactory.createEntityManager();
    tx = entityManager.getTransaction();
    tx.begin();
    teacher = entityManager.find(Teacher.class, persistedId);
    tx.commit();
    entityManager.close();
    logger.info("merge() execute ,Persisted teacher: {}", teacher);
}
teacher: Student{id=null, email='new_email@gmail.com'} is transient state
Hibernate: 
   call next value for hibernate_sequence
teacher: Student{id=1, email='new_email@gmail.com'} is persistent state
Hibernate: 
   insert 
   into
       teachers
       (email, id) 
   values
       (?, ?)
teacher: Student{id=1, email='update_email@gmail.com'} is detached state
Hibernate: 
   select
       teacher0_.id as id1_0_0_,
       teacher0_.email as email2_0_0_ 
   from
       teachers teacher0_ 
   where
       teacher0_.id=?
teacher: Student{id=1, email='update_email@gmail.com'} is persistent state
Hibernate: 
   update
       teachers 
   set
       email=? 
   where
       id=?
Hibernate: 
   select
       teacher0_.id as id1_0_0_,
       teacher0_.email as email2_0_0_ 
   from
       teachers teacher0_ 
   where
       teacher0_.id=?
merge() execute ,Persisted teacher: Student{id=1, email='update_email@gmail.com'}

通过上面的代码可以知道,当一个对象进入detached状态后,可以通过merge方法让对象再次进入持久化的状态,如果detached状态的对象在数据库中存在,此时如果此对象的状态有改变,那么调用merge方法的时候,会先查询出来这条数据,然后执行更新语句。

用我们的例子来说就是teacher对象通过persist()方法存入数据库后,此时这个对象是包含一个id的,及时处于游离态,它也包含这个id,如果不对这个对象更改,直接调用merge()的话,此时只会发出查询语句;如果改变对象,则发出更新语句。我这里是验证了改变对象的情况,有兴趣的可以试试不改变的情况。

版权声明:著作权归作者所有。

学习到了很多知识,感谢分享
相关推荐

JPA实体状态学习-(瞬时态:Transient)

为了学习实体的状态,我们还是贴出这张实体状态转换迁移图:Transient(瞬时态)按照上图的描述,java对象在内存中被赋值后,没有调用entityManager.persist()方法之前实体对象所处的状态。举个例子:Teacher teacher = new Teacher("email@dot.com");此时,实例teacher就处于new/transient态(备注:这里的new和tr

JPA实体状态学习-(持久态:Persistent)

今天我们继续学习JPA的实体状态转化,老规矩贴上实体转化的转化图: 上一节我们学习了:entityManager调用persist()方法后,实体的状态从transient到persistent,这个时候对persistent状态的实体改变也会同步持久化到数据库,执行tx.commit()之后实体进入detached状态,此时对实体进行改变后不会同步到数据库。今天我们来看看transie

获取curl的http response状态码

可以使用以下脚本获取curl请求返回的状态码:curl -w '%{response_code}\n' -so /dev/null $URL其中$URL是一个变量,可以使用实际测试的url替换。如请求百度:curl -w '%{response_code}\n' -so /dev/null https://baidu.com输出结果:302

自定义React Hooks(记录先前状态):usePrevious

usePrevious Hoos可以用来存储props或以前的状态。 首先,创建一个接受值的Hook。 然后,我们使用useRef Hook为该值创建一个ref。 最后,使用useEffect记住最新值。代码示例:const usePrevious = value => { const ref = React.useEffect(); React.u

thenjs 学习

thenjs 是一个js的异步控制流程库 特点 可以像标准的Promise那样,把N多异步回调函数写成一个长长的then链,并且比Promise更简洁自然。因为使用标准Promise的then链,其中的异步函数都必须转换成Promise,Thenjs则无需转换,像使用CallBack一样执行异步函数即可。 强大的Error机制,可以捕捉任何同步和异步的异步错误。 开启debug模式

Android保存及恢复Activity的状态

Android保存Activity状态有两种方式:activity保存以及持久化保存。这里主要介绍activity保存。保存Activity状态基于Activity保存状态需要重写onSaveInstanceState(Bundle savedInstanceState)方法。示例:@Override public void onSaveInstanceState(B