1
votes

I have the following Repository:

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

}

I'm trying to get all Tables with a certain databaseId which matches the given predicate. But I'm getting an 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$1(ParameterBinderFactory.java:139)
    at java.util.stream.ReferencePipeline$3$1.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)

That's the REST endpoint where I'm calling this method:

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

Perhaps, someone got Querydsl working with findBy-methods?

It works perfectly fine, if I'm just calling findAll like this:

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

But it doesn't work with findBy:

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

2 Answers

2
votes

This is not supported. You probably should just add the constraint on the DatabaseId to your Predicate.

One way to achieve that is to have a default implementation of your method, create a new Predicate from the one passed as an argument and use that in a call to findAll.

There is actually a JIRA issue about this (or something rather similar).

0
votes

Thanks to Jens Schauder I figured it out. What I'm doing now is creating a new Predicate based on the existing one and add the constraint for the databaseId and then just call the standard findAll() method:

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