如何重新实现JpaRepository的按示例查询方法以忽略软删除的实体

时间:2019-02-26 23:00:23

标签: java spring spring-data-jpa soft-delete query-by-example

在当前项目中,我有一个AuditableEntity抽象类,大多数其他实体都从该抽象类继承。 AuditableEntity指定了createdAtupdatedAt列(其值通过Spring的@CreatedDate@LastModifiedDate注释自动填充)以及deletedAt列,由于Spring不支持(据我所知)开箱即用的软件删除,因此需要手动执行。 AuditableEntity看起来像这样:

@Getter
@Setter
@MappedSuperclass
@EntityListeners(AuditingEntityListener.class)
@JsonIgnoreProperties(
    value = {"createdAt", "updatedAt", "deletedAt"},
    allowGetters = true
)
public abstract class AuditableEntity<T> extends IdentifiableEntity<T> implements Serializable {
    @CreatedDate
    @Column(name = "dba_ins_ymd", nullable = false, updatable = false)
    private Instant createdAt;

    @LastModifiedDate
    @Column(name = "dba_upd_ymd", nullable = false)
    private Instant updatedAt;

    @Column(name = "dba_del_ymd")
    private Instant deletedAt;
}

然后,由于有不同的StackOverflow答案,我有一个SoftDeleteJpaRepository接口(从JpaRepository继承),该接口会自动忽略软删除的条目,如下所示:

@NoRepositoryBean
public interface SoftDeleteJpaRepository<T extends AuditableEntity<ID>, ID> extends JpaRepository<T, ID> {
    @Override
    @Transactional(readOnly = true)
    @Query("select e from #{#entityName} e where e.deletedAt is null")
    List<T> findAll();

    @Override
    @Transactional(readOnly = true)
    @Query("select e from #{#entityName} e where e.deletedAt is null order by ?1")
    List<T> findAll(Sort sort);

    @Override
    @Transactional(readOnly = true)
    @Query("select e from #{#entityName} e where e.id in ?1 and e.deletedAt is null")
    List<T> findAllById(Iterable<ID> ids);

    @Override
    default void deleteInBatch(Iterable<T> entities) {
        throw new NotImplementedException("Not implemented yet");
    }

    @Override
    default void deleteAllInBatch() {
        throw new NotImplementedException("Not implemented yet");
    }

    @Override
    @Transactional(readOnly = true)
    @Query("select e from #{#entityName} e where e.id = ?1 and e.deletedAt is null")
    T getOne(ID id);

    @Override
    @Transactional(readOnly = true)
    @Query("select e from #(#entityName) e where e.deletedAt is null")
    default Page<T> findAll(Pageable pageable) {
        throw new NotImplementedException("Not implemented yet");
    }

    @Override
    @Transactional(readOnly = true)
    @Query("select e from #{#entityName} e where e.id = ?1 and e.deletedAt is null")
    Optional<T> findById(ID id);

    @Override
    default boolean existsById(ID id) {
        return getOne(id) != null;
    }

    @Override
    @Transactional(readOnly = true)
    @Query("select count(e) from #{#entityName} e where e.deletedAt is null")
    long count();

    @Override
    @Transactional
    @Query("update #{#entityName} e set e.deletedAt = current_timestamp where e.id = ?1")
    @Modifying
    void deleteById(ID id);

    @Override
    @Transactional
    default void delete(T entity) {
        deleteById(entity.getId());
    }

    @Override
    @Transactional
    default void deleteAll(Iterable<? extends T> entities) {
        entities.forEach(entity -> deleteById(entity.getId()));
    }

    @Override
    @Transactional
    @Query("update #{#entityName} e set e.deletedAt = current_timestamp")
    @Modifying
    void deleteAll();

    @Query("select e from #{#entityName} e where e.deletedAt is not null")
    @Transactional(readOnly = true)
    List<T> findSoftDeleted();
}

基本上,到目前为止,混合的@Query注释和一些default实现的混合。

最后,这是一个问题:对于我的一些用例,我还需要使用示例查询,因此我需要以类似的方式调整<S extends T> List<S> findAll(Example<S> example)<S extends T> Page<S> findAll(Example<S> example, Pageable pageable)方法,这样他们将自动忽略deletedAt列中包含任何值的条目。但坦率地说,我不知道从哪里开始或如何做。

我尝试查找Spring如何实现这些方法,但我只能找到QueryByExampleExecutor接口中的方法名称。 IDEA表明该方法的唯一实现是在SimpleJpaRepository中,但这是从中获取灵感的正确地方吗?这两种方法的通用版本(会自动忽略软删除的条目)会是什么样子?

0 个答案:

没有答案