Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Spring Data REST custom finder for JpaRepository

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.

like image 204
nyl66 Avatar asked Nov 12 '22 18:11

nyl66


1 Answers

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());
    }
}
like image 141
michaeligler Avatar answered Jan 04 '23 02:01

michaeligler