5
votes

I am looking to build a REST interface with a generic finder. The idea is to provide a search form where users can get all records by not providing any parameter or refine their search results by typing any combination of the fields.

The simple example I have annotates the JpaRepository with @RestResource which provides a nice out of the box way to add finders either by using @Query or by method name conventions

@RestResource(path = "users", rel = "users")
public interface UserRepository extends JpaRepository<User, Long>{
    public Page<User> findByFirstNameStartingWithIgnoreCase(@Param("first") String fName, Pageable page);
}

I am looking to add a custom finder that would map my parameters and would leverage the paging, sorting and REST support where the actual implementation query will be composed dynamically (probably using QueryDSL) the method will have n parameters (p 1 ... p n) and will look like:

public Page<User> findCustom(@Param("p1") String p1, @Param("p2") String p2, ... @Param("pn") String pn, Pageable page);

I have tried the approach described in:

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

but my custom method is not available from the repository's REST interface (/users/search)

I hope someone already figured this out and would be kind to give me some direction.

1
did you get anywhere with this? - wenic
Not really. I was already doing most of the custom queryDSL predicate queries in the Controller but would still be nice to know if that is possible and how. - nyl66
I am trying to solve the same problem. When you implemented the queries in the controller, how did you handle paging? - JBCP

1 Answers

1
votes

Try something like this but of course adopted to your scenario:

public interface LocationRepository extends CrudRepository, 
    PagingAndSortingRepository,
    LocationRepositoryExt {

}
public interface LocationRepositoryExt {
    @Query
    public List findByStateCodeAndLocationNumber(@Param("stateCode") StateCode stateCode,   @Param("locationNumber") String locationNumber);
}
class LocationRepositoryImpl extends QueryDslRepositorySupport implements LocationRepositoryExt {

    private static final QLocation location = QLocation.location;

    public LocationRepositoryImpl() {
        super(Location.class);
    }

    @Override
    public Page findByStateAndLocationNumber(@Param("state") State state, @Param("locationNumber") String locationNumber, Pageable pageable) {

        List locations = from(location)
                .where(location.state.eq(state)
                        .and(location.locationNumber.eq(locationNumber)))
                .list(location);

        return new PageImpl(locations, pageable, locations.size());
    }
}