持续存在的实体

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

拯救实体

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

实体状态检测策略

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

  1. 版本-属性和Id-属性检查(默认): 默认情况下,Spring Data JPA 首先检查是否存在非原语类型的 Version-属性。 如果存在,则该实体被视为新实体,且该性质的价值为. 没有这样的版本属性,Spring Data JPA 会检查给定实体的标识符属性。 如果标识符属性为,则假设该实体是新的。 否则,人们就认为它不是新的。 与其他Spring Data模块不同,JPA考虑了0(零)作为实体的第一个插入版本,因此,原始版本性质不能用来判断某个实体是否新。spring-doc.cadn.net.cn

  2. 实施持久性: 如果一个实体实现持久性,Spring Data JPA 将新的检测委托给isNew(...)实体的方法。 详情请参见Java文档spring-doc.cadn.net.cn

  3. 实施实体信息: 你可以自定义实体信息抽象形式用于SimpleJpaRepository通过创建 的子类实现JpaRepositoryFactory并且覆盖getEntityInformation(...)相应地进行方法。然后你必须注册 的自定义实现JpaRepositoryFactory作为春豆。请注意,这通常很少是必要的。详情请参见Java文档spring-doc.cadn.net.cn

选项1不适用于使用手动分配标识符且无版本属性的实体,因为这些标识符总是非. 在这种情景下,常见的模式是使用一个通用基类,默认以瞬态标志表示新实例,并在持久化作时使用 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()......合并().
3 声明使用 JPA 实体回调的方法,使得在仓库调用后,标志被切换为表示已有实体保存(...)或者由持久化提供者创建实例。