Hibernate实体对象的四种状态以及转换关系

Spring Data JPA 可以理解为 是对 JPA 规范的二次封装和抽象,底层还是使用了 Hibernate 的 JPA 技术实现。因此,还是要不辞劳苦地翻阅Hibernate文档。最新的Hibernate文档中为Hibernate对象定义了四种状态(原来是三种状态,面试的时候基本上问的也是三种状态),分别是:瞬时态(new, or transient)、持久态(managed, or persistent)、游状态(detached)和移除态(removed,以前Hibernate文档中定义的三种状态中没有移除态),如下图所示,就以前的Hibernate文档中移除态被视为是瞬时态。

 

  • 瞬时态:当new一个实体对象后,这个对象处于瞬时态,即这个对象只是一个保存临时数据的内存区域,如果没有变量引用这个对象,则会被JVM的垃圾回收机制回收。这个对象所保存的数据与数据库没有任何关系,除非通过Session的save()、saveOrUpdate()、persist()、merge()方法把瞬时态对象与数据库关联,并把数据插入或者更新到数据库,这个对象才转换为持久态对象。
  • 持久态:持久态对象的实例在数据库中有对应的记录,并拥有一个持久化标识(ID)。对持久态对象进行delete操作后,数据库中对应的记录将被删除,那么持久态对象与数据库记录不再存在对应关系,持久态对象变成移除态(可以视为瞬时态)。持久态对象被修改变更后,不会马上同步到数据库,直到数据库事务提交。
  • 游离态:当Session进行了close()、clear()、evict()或flush()后,实体对象从持久态变成游离态,对象虽然拥有持久和与数据库对应记录一致的标识值,但是因为对象已经从会话中清除掉,对象不在持久化管理之内,所以处于游离态(也叫脱管态)。游离态的对象与临时状态对象是十分相似的,只是它还含有持久化标识。
  • 移除态:当调用EntityManger对实体进行delete后,该实体对象就处于删除状态。其本质也就是一个瞬时状态的对象

1、更新的方法不开启事物处理,然后使用save()等方法更新操作即可(缺点:没有事物无法回滚,不能保证数据一致性)

@Test
public void testUpdate(){
    // 持久化状态的,不过没有加事物控制
    User user = this.userCrudRepository.findById(1L).get();
    user.setUsername("王小红");
    this.userCrudRepository.save(user);
}

2、因持久层框架JPA自身的机制,会在事务提交后将持久状态的对象自动更新到数据库,为了避免自动更新,我们可以创建一个对象,设置好属性后再调用save()方法更新数据(缺点:比较繁琐,代码也会变得不够简洁)

@Test
@Transactional
public void testUpdate(){
    // 持久化状态的,不过没有加事物控制
    User user = this.userCrudRepository.findById(1L).get();
    User userNew = new User();
    userNew.setId(user.getId)
    userNew.setUsername("admin");
    userNew.setPassword(user.getPassword);
    this.userCrudRepository.save(userNew);
}

3、把持久态的对象变成游离态即可,有如下三种方法(缺点也是需要注入EntityManager)

  • close() 方法:关闭session可以,但是若后面还要用session这个方法就不太好了
  • clear() 方法:将session中所有的对象全部清除缓存
  • evict() 方法:将某一个对象清楚缓存session(推荐)
@PersistenceContext
private EntityManager entityManager;

@Test
@Transactional
public void testUpdate(){
    // 持久化状态的,不过没有加事物控制
    User user = this.userCrudRepository.findById(1L).get();
    // 检查对象是否是持久化态
    if (entityManager.contains(user)) {
        // 获取session
        Session session = entityManager.unwrap(org.hibernate.Session.class);
        // 转换成游离态
        session.evict(entry);
    }
    user.setUsername("王小红");
    this.userCrudRepository.save(user);
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值