Search code examples
javaspring-data-jpaspring-data

Using @MappedSuperclass in spring repository @Query


I am trying to define a common query for all repositories extending my base repository:

@NoRepositoryBean
public interface DocumentRepository<T extends BaseDocument> extends JpaRepository<T, Long> {

    @Query(value = "FROM BaseDocument bd WHERE (bd.createdAt IS NULL OR :to IS NULL OR bd.createdAt < :to) AND (bd.deletedAt IS NULL OR :from IS NULL OR bd.deletedAt > :from)")
    Iterable<T> findAllActiveBetween(OffsetDateTime from, OffsetDateTime to);
}

@MappedSuperclass
@Where(clause="deleted_at IS NULL")
abstract public class BaseDocument {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;

    private OffsetDateTime createdAt;

    private OffsetDateTime deletedAt;
}

The problematic part is using BaseDocument in @Query. Is it possible to define such a method without duplication in all sub-repositories?


Solution

  • This is possible with spel-expressions, specifically #{#entityName} which is usable on spring-data-repositories and expands to the domain type of your repository.

    All you need to do is replace your BaseDocument with #{#entityName}.

    @NoRepositoryBean
    public interface DocumentRepository<T extends BaseDocument> extends JpaRepository<T, Long> {
    
        @Query(value = "FROM #{#entityName} bd WHERE (bd.createdAt IS NULL OR :to IS NULL OR bd.createdAt < :to) AND (bd.deletedAt IS NULL OR :from IS NULL OR bd.deletedAt > :from)")
        Iterable<T> findAllActiveBetween(OffsetDateTime from, OffsetDateTime to);
    }