In my app I have a foreign key relation between Things and Stuff where a given Thing may contain hundreds of Stuffs and I'm using Spring Data JPA to expose the Thing and Stuff repository's.
I want to display all the Stuff associated with the users selected Thing, but because of the size of the return I want to page the Stuff result.
Searching showed that it is not possible to add paging functionality to the embedded stuff links from a Thing return, so the below link as returned from my Thing repository can never be paged:
"stuff": {
"href": "http://localhost:8080/api/things/1/stuff"
}
So I have added a custom method to my Stuff repository to get all Stuff by thing Id, and that works fine when called directly.
I want to add a Link to the Thing Resource return pointing at the custom search method to get all the assocated Stuff, but when I use the ControllerLinkBuilder.linkTo() method it fails with
java.lang.IllegalArgumentException: 'uriTemplate' must not be null
at org.springframework.util.Assert.hasText(Assert.java:181) ~[spring-core-4.3.11.RELEASE.jar:4.3.11.RELEASE]
at org.springframework.web.util.UriTemplate.<init>(UriTemplate.java:61) ~[spring-web-4.3.11.RELEASE.jar:4.3.11.RELEASE]
Stuff Repo:
public interface StuffRepo extends JpaRepository<Stuff, Long> {
Page<Stuff> findByThingId(@Param("thingId") Long thingId, Pageable pageable);
}
Configuration:
@Bean
ThingProcessor getThingProcessor()
{
return new ThingProcessor();
}
public static class ThingProcessor implements ResourceProcessor<Resource<Thing>>{
@Override
public Resource<Thing> process(Resource<Thing> resource) {
ControllerLinkBuilder.linkTo(ControllerLinkBuilder.methodOn(StuffRepo.class).findByThingId(resource.getContent().id, null));
return resource;
}
}
Am I missing some annotation or configuration? I have tried annotating the Repo and the method with @RestResource and it makes no difference. Also is there a better way to get a paged result for the sub objects?
I got around this using the RepositoryEntityLinks
class, that gives you a list of Link objects, and from there I find the one I need using link.getRel()