此版本仍在开发中,尚不被认为是稳定的。对于最新的稳定版本,请使用 Spring Data JPA 3.5.2spring-doc.cadn.net.cn

持久化实体

本节介绍如何使用 Spring Data JPA 持久化(保存)实体。spring-doc.cadn.net.cn

保存实体

保存实体可以使用CrudRepository.save(…)方法。它使用底层 JPA 持久化或合并给定实体EntityManager.如果实体尚未持久化,Spring Data JPA 会通过调用entityManager.persist(…)方法。否则,它调用entityManager.merge(…)方法。spring-doc.cadn.net.cn

实体状态检测策略

Spring Data JPA 提供了以下策略来检测实体是否是新的:spring-doc.cadn.net.cn

  1. Version-Property 和 Id-Property 检查(默认): 默认情况下,Spring Data JPA首先检查是否存在非原始类型的Version属性。 如果有,则如果该属性的值为null. 如果没有这样的 Version 属性,Spring Data JPA 会检查给定实体的标识符属性。 如果标识符属性为null,则假定该实体是新的。 否则,它被假定为不是新的。 与其他 Spring Data 模块相比,JPA 认为0(零) 作为实体的第一个插入版本,因此,不能使用原始版本属性来确定实体是否是新的。spring-doc.cadn.net.cn

  2. 实施Persistable:如果实体实现Persistable,Spring Data JPA 将新的检测委托给isNew(…)实体的方法。 有关详细信息,请参阅 JavaDocspring-doc.cadn.net.cn

  3. 实施EntityInformation:您可以自定义EntityInformation抽象用于SimpleJpaRepository通过创建JpaRepositoryFactory并覆盖getEntityInformation(…)相应地方法。然后,您必须注册JpaRepositoryFactory作为春豆。请注意,这应该很少需要。有关详细信息,请参阅 JavaDocspring-doc.cadn.net.cn

选项 1 不适用于使用手动分配的标识符且没有版本属性的实体的选项,因为对于那些标识符将始终是非null. 该场景中的常见模式是使用具有瞬态标志的公共基类,默认指示新实例,并使用 JPA 生命周期回调在持久性作上翻转该标志:spring-doc.cadn.net.cn

示例 1.具有手动分配标识符的实体的基类
@MappedSuperclass
public abstract class AbstractEntity<ID> implements Persistable<ID> {

  @Transient
  private boolean isNew = true; (1)

  @Override
  public boolean isNew() {
    return isNew; (2)
  }

  @PostPersist (3)
  @PostLoad
  void markNotNew() {
    this.isNew = false;
  }

  // More code…
}
1 声明一个标志来保存新状态。暂时性,使其不会持久化到数据库。
2 在实现Persistable.isNew()以便 Spring Data 存储库知道是否调用EntityManager.persist()….merge().
3 使用 JPA 实体回调声明一个方法,以便在存储库调用save(…)或持久性提供程序创建的实例。