Spring存储库的自定义ResourceAssembler

时间:2018-11-15 11:13:13

标签: java spring spring-boot spring-data-rest

我使用Spring Data REST,Spring HATEOAS,Hibernate创建了Spring Boot 2应用程序。

我想创建一个自定义ResourceAssembler。我完成了创建这个bean的工作:

@Component
public class StringResourceAssembler implements ResourceAssembler<String, Resource<String>> {

    @Autowired
    private EntityLinks entityLinks;

    @Override
    public Resource<String> toResource(String question) {
        Resource<String> resource = new Resource<String>(question);
        return resource;
    }
}

我需要一个客户ResourceAssembler,因为在Spring Repository中,我有这种方法:

@Transactional
@PreAuthorize("isAuthenticated()")
public interface FrameRepository extends JpaRepository<Frame, Long> {

     @Transactional(readOnly = true)
     @Query(value = "SELECT DISTINCT f.manufacturer FROM Frame f WHERE :searchString IS NULL OR (f.manufacturer LIKE CONCAT(:searchString,'%')) GROUP BY f.manufacturer ORDER BY f.manufacturer")
     public Page<String> manufacturerAutocomplete(@Param("searchString") String searchString, Pageable pageable);

如您所见,我的方法是由Spring Data REST导出的,并且它重建了一个字符串值页面(枚举对我也有同样的问题)。

不幸的是,我有这个异常:

15/11/2018 12:09:45,054 ERROR http-nio-8082-exec-7 RepositoryRestExceptionHandler:168 - Couldn't find PersistentEntity for type class java.lang.String!
java.lang.IllegalArgumentException: Couldn't find PersistentEntity for type class java.lang.String!
    at org.springframework.data.mapping.context.PersistentEntities.lambda$getRequiredPersistentEntity$2(PersistentEntities.java:78) ~[spring-data-commons-2.0.8.RELEASE.jar:2.0.8.RELEASE]
    at java.util.Optional.orElseThrow(Optional.java:290) ~[?:1.8.0_181]
    at org.springframework.data.mapping.context.PersistentEntities.getRequiredPersistentEntity(PersistentEntities.java:77) ~[spring-data-commons-2.0.8.RELEASE.jar:2.0.8.RELEASE]
    at org.springframework.data.rest.webmvc.PersistentEntityResourceAssembler.wrap(PersistentEntityResourceAssembler.java:72) ~[spring-data-rest-webmvc-3.0.8.RELEASE.jar:3.0.8.RELEASE]
    at org.springframework.data.rest.webmvc.PersistentEntityResourceAssembler.toResource(PersistentEntityResourceAssembler.java:55) ~[spring-data-rest-webmvc-3.0.8.RELEASE.jar:3.0.8.RELEASE]
    at org.springframework.data.rest.webmvc.PersistentEntityResourceAssembler.toResource(PersistentEntityResourceAssembler.java:38) ~[spring-data-rest-webmvc-3.0.8.RELEASE.jar:3.0.8.RELEASE]
    at org.springframework.data.web.PagedResourcesAssembler.createResource(PagedResourcesAssembler.java:208) ~[spring-data-commons-2.0.8.RELEASE.jar:2.0.8.RELEASE]
    at org.springframework.data.web.PagedResourcesAssembler.toResource(PagedResourcesAssembler.java:120) ~[spring-data-commons-2.0.8.RELEASE.jar:2.0.8.RELEASE]
    at org.springframework.data.rest.webmvc.AbstractRepositoryRestController.lambda$entitiesToResources$3(AbstractRepositoryRestController.java:95) ~[spring-data-rest-webmvc-3.0.8.RELEASE.jar:3.0.8.RELEASE]
    at java.util.Optional.orElseGet(Optional.java:267) ~[?:1.8.0_181]
    at org.springframework.data.rest.webmvc.AbstractRepositoryRestController.entitiesToResources(AbstractRepositoryRestController.java:95) ~[spring-data-rest-webmvc-3.0.8.RELEASE.jar:3.0.8.RELEASE]
    at org.springframework.data.rest.webmvc.AbstractRepositoryRestController.toResources(AbstractRepositoryRestController.java:78) ~[spring-data-rest-webmvc-3.0.8.RELEASE.jar:3.0.8.RELEASE]
    at org.springframework.data.rest.webmvc.RepositorySearchController.lambda$toResource$1(RepositorySearchController.java:209) ~[spring-data-rest-webmvc-3.0.8.RELEASE.jar:3.0.8.RELEASE]
    at java.util.Optional.map(Optional.java:215) ~[?:1.8.0_181]
    at org.springframework.data.rest.webmvc.RepositorySearchController.toResource(RepositorySearchController.java:206) ~[spring-data-rest-webmvc-3.0.8.RELEASE.jar:3.0.8.RELEASE]
    at org.springframework.data.rest.webmvc.RepositorySearchController.executeSearch(RepositorySearchController.java:190) ~[spring-data-rest-webmvc-3.0.8.RELEASE.jar:3.0.8.RELEASE]
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:1.8.0_181]
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[?:1.8.0_181]
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:1.8.0_181]
    at java.lang.reflect.Method.invoke(Method.java:498) ~[?:1.8.0_181]
    at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:209) ~[spring-web-5.0.7.RELEASE.jar:5.0.7.RELEASE]
    at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:136) ~[spring-web-5.0.7.RELEASE.jar:5.0.7.RELEASE]
    at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:102) ~[spring-webmvc-5.0.7.RELEASE.jar:5.0.7.RELEASE]
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:877) ~[spring-webmvc-5.0.7.RELEASE.jar:5.0.7.RELEASE]
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:783) ~[spring-webmvc-5.0.7.RELEASE.jar:5.0.7.RELEASE]
    at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87) ~[spring-webmvc-5.0.7.RELEASE.jar:5.0.7.RELEASE]
    at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:991) [spring-webmvc-5.0.7.RELEASE.jar:5.0.7.RELEASE]
    at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:925) [spring-webmvc-5.0.7.RELEASE.jar:5.0.7.RELEASE]
    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:974) [spring-webmvc-5.0.7.RELEASE.jar:5.0.7.RELEASE]
    at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:866) [spring-webmvc-5.0.7.RELEASE.jar:5.0.7.RELEASE]

有没有办法让我的ResourceAssembler与Spring Data REST一起使用?

2 个答案:

答案 0 :(得分:0)

您的存储库从 "description": "", "main": "index.js", "scripts": { "start": "node server.js", "server": "nodemon server.js", "client-install": "npm install --prefix client", "client": "npm start --prefix client", "dev": "concurrently \"npm run client\" \"npm run server\"" }, "author": "", "license": "ISC", "dependencies": { "concurrently": "^4.0.1", "express": "^4.16.4", "jsonwebtoken": "^8.3.0", "mongoose": "^5.3.4", "node": "^8.10.0", "nodemon": "^1.18.4", "passport": "^0.4.0", "passport-jwt": "^4.0.0", "react-scripts": "1.0.11", }, "devDependencies": { "nodemon": "^1.18.4" } } 扩展,因此它期望的是JpaRepository<Frame, Long>,而不是Page<Frame>

答案 1 :(得分:0)

  

创建一个要在其中保存结果的类。

    @AllArgsConstructor
    @NoArgsConstructor
    public class Result {
        private String manufacturer;
    }
  

RepositoryMethod:

@Transactional(readOnly = true)
@Query(value = "SELECT New Result(DISTINCT f.manufacturer) FROM Frame f WHERE :searchString IS NULL OR (f.manufacturer LIKE CONCAT(:searchString,'%')) GROUP BY f.manufacturer ORDER BY f.manufacturer")
public Page<Result> manufacturerAutocomplete(@Param("searchString") String searchString, Pageable pageable);