在Spring存储库@Query中使用@MappedSuperclass

问题描述 投票:0回答:2

我正在尝试为扩展我的基本存储库的所有存储库定义通用查询:

@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;
}

有问题的部分是在@Query 中使用BaseDocument。 可以在所有子存储库中定义这样的方法而不重复吗?

spring-data-jpa spring-data
2个回答
2
投票

当您使用@MappedSuperclass时,继承的类不共享可供选择的表,因此每个类都需要单独的查询。存储库的继承在这里无法帮助您。

如果您使用其他继承策略,例如联合多表继承,则可以从超类的表中进行选择,然后您可以使用java对象进行导航。如果您需要在查询中使用子类的属性,那么每个子类当然需要实现自己的查询。

@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);
}

@Entity
@Inheritance(strategy=InheritanceType.JOINED)
@DiscriminatorColumn(name="BaseDocument_TYPE")
@Table(name="BaseDocument")
abstract public class BaseDocument {

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

    private OffsetDateTime createdAt;

    private OffsetDateTime deletedAt;
}

@Entity
@DiscriminatorValue("TextDocument")
@Table(name="TextDocument")
public class TextDocument extends BaseDocument {
  private String text;
}

@Entity
@DiscriminatorValue("AudioDocument")
@Table(name="AudioDocument")
public class AudioDocument extends BaseDocument {
  private byte [] audio;
}


0
投票

这可以通过 spel-expressions 实现,特别是 #{#entityName},它可在 spring-data-repositories 上使用,并扩展到存储库的域类型。

您需要做的就是将

BaseDocument
替换为
#{#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);
}
© www.soinside.com 2019 - 2024. All rights reserved.