Spring 数据 JPA - PagingAndSortingRepository 和 Querydsl 谓词不能与 findByAttribute 一起使用

Spring Data JPA - PagingAndSortingRepository and Querydsl Predicate not working with findByAttribute

我有以下存储库:

public interface TableRepository extends 
    PagingAndSortingRepository<Table, Integer>, 
    QuerydslPredicateExecutor<Table>, 
    QuerydslBinderCustomizer<QTable> 
{
    Page<Table> findAllByDatabaseId(Integer databaseId, Predicate predicate, Pageable pageable);

}

我正在尝试获取所有具有与给定谓词匹配的特定 databaseId 的表。但是我收到了 IndexOutOfBoundsException:

java.lang.IndexOutOfBoundsException: Index: 1, Size: 1
    at java.util.ArrayList.rangeCheck(ArrayList.java:657)
    at java.util.ArrayList.get(ArrayList.java:433)
    at java.util.Collections$UnmodifiableList.get(Collections.java:1309)
    at org.springframework.data.jpa.repository.query.QueryParameterSetterFactory$CriteriaQueryParameterSetterFactory.create(QueryParameterSetterFactory.java:271)
    at org.springframework.data.jpa.repository.query.ParameterBinderFactory.lambda$createQueryParameterSetter(ParameterBinderFactory.java:139)
    at java.util.stream.ReferencePipeline.accept(ReferencePipeline.java:193)
    at java.util.Spliterators$ArraySpliterator.tryAdvance(Spliterators.java:958)
    at java.util.stream.ReferencePipeline.forEachWithCancel(ReferencePipeline.java:126)
    at java.util.stream.AbstractPipeline.copyIntoWithCancel(AbstractPipeline.java:498)
    at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:485)
    at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:471)
    at java.util.stream.FindOps$FindOp.evaluateSequential(FindOps.java:152)
    at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
    at java.util.stream.ReferencePipeline.findFirst(ReferencePipeline.java:464)

这是我调用此方法的 REST 端点:

public Page<TableProjection> getTablesByDatabase(
    @PathVariable("databaseId") final Integer databaseId,
    final Pageable pageable,
    @QuerydslPredicate(root = Table.class) final Predicate predicate) 
{
    tableRepository.findAllByDatabaseId(databaseId, predicate, pageable);
}

也许有人让 Querydsl 使用 findBy 方法?

它工作得很好,如果我只是像这样调用 findAll:

Page<Table> findAll(Predicate predicate, Pageable pageable);

但它不适用于 findBy:

Page<Table> findAllByDatabaseId(Integer databaseId, Predicate predicate, Pageable pageable);

这是不支持的。您可能应该将 DatabaseId 上的约束添加到谓词中。

实现这一点的一种方法是使用您的方法的默认实现,从作为参数传递的那个创建一个新的 Predicate 并在对 findAll 的调用中使用它。

实际上有一个关于此的 JIRA 问题(或类似的问题)。

多亏了 Jens Schauder,我才弄明白了。我现在正在做的是在现有的基础上创建一个新的 Predicate 并为 databaseId 添加约束,然后调用标准 findAll() 方法:

public Page<TableProjection> getTablesByDatabase(
    @PathVariable("databaseId") final Integer databaseId,
    final Pageable pageable,
    @QuerydslPredicate(root = Table.class) final Predicate predicate) 
{
    QTable t = QTable.table;
    BooleanBuilder where = new BooleanBuilder();
    where.and(predicate).and(t.database.id.eq(databaseId));

    final Page<Table> tables = tableRepository.findAll(where, pageable);
}