从零开始 Spring Boot 49:Hibernate Entity Lifecycle

从零开始 Spring Boot 49:Hibernate Entity Lifecycle

spring boot

图源:简书 (jianshu.com)

本文将介绍 Hibernate 的 Session 接口,以及如何用 Session 的相关 API 转换实体(Entity)的生命周期状态。

如果缺少的 JPA 和 Hibernate 的基本认识,可以阅读前篇文章

概念

持久化上下文

在 JPA 的相关概念中,存在一个持久化上下文(Persistence Context)。

持久化上下文处于代码端与数据库之间,充当一个容器或一级缓存的作用,负责管理运行时的实体(Entity),它可以在合适的时间从数据库中加载数据到实体对象,也可以将实体对象“回写”到数据库。

在 Hibernate 中,持久化上下文由 org.hibernate.Session实例表示,在标准的 JPA 中,表现为jakarta. persistence. EntityManager。在使用 Hibernate 的时候,这两者都可以使用,但相比EntityManagerSession是一个更丰富的接口,有时候可能会更有用。

实体状态

与持久化上下文(本文特指Session)关联的实体实例是存在状态的,它们必然处于以下三种状态之一:

  • transient,此实例从来没有附加到 Session,且数据库中也不存在对应的行数据,这只是一个为保存数据到数据库创建的新对象。
  • persistent,实例与唯一的 Session 对象关联,并对应数据库中的一条记录。Session 刷新后,将检查数据一致性,并在不一致的情况下更新数据库中的数据。
  • detached,实例曾经与 Session 关联(处于 persistent 状态),但当前已经不是。将实例从 Session 逐出(Session.evict)、关闭 Session 或将实例序列化/反序列化都会让实例进入这个状态。

可以通过 Session 的 API 将实例的状态进行转换:

image-20230628104714585

图源:Baeldung

图中的一些方法调用已经作废,比如save()

持久的实体是最为关键的,处于这种状态的实体实例会被 Session 管理和监控,对这些实体的任何改变都会被记录,且在事务提交或 Session 关闭时回写到数据库,且不需要我们调用任何其它方法。

持久实体也被称作“被管理的实体”(Managed Entity)。实际上这些实体都有一个唯一的数据库标识(database identifier),所以对这些实体的任何更改都会被传播到数据库。

  • 这也是为什么在实体类中要用@Id定义一个主键字段。
  • 要牢记,只有在事务提交后才会真正向数据库中插入数据,但在此之前,也会为持久实体分配数据库标识。

Session API

下面我们看相关的 Session API。

在介绍相关 API 之前,需要对一些用到的工具类进行简要说明。

@Component
public class HibernateLifecycleUtil {
   
    @SneakyThrows
    public List<EntityEntry> getManagedEntities(Session session) {
   
        // 传入的参数 session 不能是一个代理对象,否则会报类型转换错误
        Map.Entry<Object, EntityEntry>[] entries = ((SessionImplementor) session).getPersistenceContext().reentrantSafeEntityEntries();
        return Arrays.stream(entries).map(e -> e.getValue()).collect(Collectors.toList());
    }
}

HibernateLifecycleUtil.getManagedEntities方法可以返回 Session 管理的实体实例(persistent)。

public class DirtyDataRecorderInterceptor implements Interceptor, Serializable {
   
    private static final List<Object> dirtyEntities = Collections.synchronizedList(new ArrayList<>());

    
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值