Spring Data Rest JpaRepository中@NamedQuery覆盖findAll

8

有没有一种方法可以覆盖Spring Data Rest执行的findAll查询?

我需要一种根据特定标准过滤结果的方法,似乎使用 @NamedQuery 就是我要找的,因此我设置了一个测试。

@Entity
@Table(name = "users")
@NamedQueries({
    @NamedQuery(name = "User.findAll", query="SELECT u FROM User u WHERE u.username = 'test'"), 
    @NamedQuery(name = "User.findNameEqualsTest", query="SELECT u FROM User u WHERE u.username = 'test'")   
})
public class User implements Serializable, Identifiable<Long> { }

有了这个设置,我期望SDR会使用我的findAll()查询(返回1个结果),但实际上它执行了相同的findAll逻辑(返回所有结果)。

在我的Repository中,我添加了:

@Repository
@RestResource(path = "users", rel = "users")
public interface UserJpaRepository extends JpaRepository<User, Long> {

    public Page<User> findNameEqualsTest(Pageable pageable);
}

在这种情况下,它确实会使用提供的@NamedQuery。那么...
我应该如何覆盖默认的findAll()逻辑?我需要构建一个复杂的条件集并将其应用于结果集。
2个回答

15
在即将发布的Spring Data JPA 1.5版本中(我们里程碑存储库中已经有了RC版本),您可以在存储库接口中重新声明方法并用@Query进行注释,以触发执行查询方法。这将导致命名查询被查找,就像您已经习惯了的查询方法一样:
interface UserJpaRepository extends PagingAndSortingRepository<User, Long> {

  @Query
  List<User> findAll();

  Page<User> findNameEqualsTest(Pageable pageable);
}

关于您的存储库声明,有几点需要注意:

  • 您不需要在接口上注释@Repository。该注释在这里根本没有任何效果。
  • 您的@RestResource注释以一种方式配置导出器,在Spring Data REST 2.0(也已经在RC中)中将成为默认设置。向前看,更喜欢使用@RestRepositoryResource,但正如我所说:复数形式将成为默认设置。
  • 我们通常不建议扩展特定于存储的接口,而是使用CrudRepositoryPagingAndSortingRepository

1
非常感谢你,Oliver!昨晚我看了你的Repositories Deepdive演讲,对我真的有所帮助。今天我会做一些改变,以更好地实现你的最佳实践。 - Ethan Anderson

5

是的,您可以创建自己的Repository接口实现。在这个链接中有相关的详细说明:

http://docs.spring.io/spring-data/jpa/docs/1.4.3.RELEASE/reference/html/repositories.html#repositories.custom-implementations

Repository

   @Repository
    public interface PagLogRepository extends JpaRepository<PagLogEntity, Long>, PagLogCustomRepository {

自定义界面

public interface PagLogCustomRepository {
PagLogEntity save(SalesForceForm salesForceForm) throws ResourceNotFoundException;

自定义实现
public class PagLogRepositoryImpl implements PagLogCustomRepository {
@Override
    public PagLogEntity save(final SalesForceForm salesForceForm) throws ResourceNotFoundException {

        query = emEntityManager.createNamedQuery("findItemFileByDenormalizedSku", ItemFileEntity.class);
        query.setParameter("skuValue", rawSku);

不要覆盖 save 方法,使用 findAll 方法来创建复杂的自定义操作。


已经实现并且正常工作了。之前我一直在键盘上敲打,直到意识到类名在这个过程中的重要性。 - Ethan Anderson
确实,这是一个非常常见的问题,在SOverflow上已经被多次提问了,教程应该在那里加上一条注释。 - Koitoer
1
从Spring Data JPA 1.5开始,不再需要自定义实现来实现此目的。有关详细信息,请参见我的答案 - Oliver Drotbohm
不需要这样做,这并不意味着答案不正确,但听起来很棒,新版本的东西。 - Koitoer

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接