返回

Entity在JPA的生命周期及相互转换

后端

Entity 的生命周期:状态转换的深入探索

在 Java 持久化 API (JPA) 中,实体是一种持久化对象,可以映射到数据库表中。实体的生命周期涵盖了从创建到销毁的整个过程,在此过程中,它会经历四个不同的状态:临时状态、持久状态、托管状态和游离状态。

实体的状态

1. 临时状态

在临时状态下,实体刚被创建,尚未与实体管理器建立关系,也没有被持久化。换句话说,它不属于实体管理器的受管对象集合。

2. 持久状态

当实体调用实体管理器的 persist() 方法时,它就会进入持久状态。此时,实体被视为数据库中的持久化记录,并受到实体管理器管理。

3. 托管状态

当实体管理器关闭时,持久状态的实体会进入托管状态。尽管实体仍然存在于内存中,但它不再由实体管理器控制。

4. 游离状态

托管状态的实体在实体管理器关闭后,如果未被卸载,则会进入游离状态。游离状态的实体不再与数据库或实体管理器有任何关联。

状态转换

实体可以在生命周期中进行状态转换。这些转换由实体管理器提供的操作(如持久化、合并、删除等)触发。

  • 临时状态到持久状态: 调用 persist() 方法。
  • 持久状态到托管状态: 实体管理器关闭。
  • 托管状态到临时状态: 调用 detach() 方法。
  • 托管状态到持久状态: 调用 merge() 方法。
  • 持久状态或托管状态到游离状态: 实体管理器关闭。

示例:Employee 实体

考虑一个 Employee 实体,它映射到 Employee 表。

@Entity
public class Employee {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String name;
}

流程:

  1. 创建一个 Employee 实例并将其持久化。
Employee employee = new Employee();
employee.setName("John Doe");
EntityManager em = entityManagerFactory.createEntityManager();
em.getTransaction().begin();
em.persist(employee);
em.getTransaction().commit();
  1. 关闭实体管理器。
em.close();
  1. 重新打开一个新的实体管理器并查找该实体。
em = entityManagerFactory.createEntityManager();
Employee employee2 = em.find(Employee.class, employee.getId());

此时,employee2 处于托管状态。

  1. 调用 detach() 方法。
em.detach(employee2);

现在,employee2 处于临时状态。

  1. 再次关闭实体管理器。
em.close();

employee2 现在处于游离状态。

常见问题解答

1. 为什么使用持久化状态?

持久化状态允许实体管理器跟踪对实体所做的更改,以便在事务提交时将这些更改刷新到数据库中。

2. 托管状态和持久状态之间的区别是什么?

托管状态的实体仍然存在于内存中,但不受实体管理器控制,而持久状态的实体受实体管理器管理,并且所有对实体所做的更改都会被跟踪。

3. 游离状态的实体有什么用?

游离状态的实体可以用于某些情况,例如在序列化实体时或将其存储在缓存中时。

4. 如何从游离状态返回到持久状态?

调用实体管理器的 merge() 方法可以将游离状态的实体返回到持久状态。

5. 什么情况下实体会进入临时状态?

实体在创建时处于临时状态,在调用实体管理器的 remove() 方法删除时也会进入临时状态。