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);
}
我有以下存储库:
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);
}