After overriding RestController method I get: org.springframework.dao.InvalidDataAccessApiUsageException: The given id must not be null

huangapple go评论104阅读模式
英文:

After overriding RestController method I get: org.springframework.dao.InvalidDataAccessApiUsageException: The given id must not be null

问题

我想将 spring-hateoas 添加到我的作品集项目中,并使其完全符合 RESTful。这意味着我需要覆盖 AbstractResource 类提供的方法(这是我 @RestController 的基类),以便根据我的需求进行编辑。当我这样做时,我会遇到 org.springframework.dao.InvalidDataAccessApiUsageException: 给定的 id 不得为空!

我的项目结构如下:

  • service 包
  1. public interface AbstractService<ENTITY extends AbstractEntity> {
  2. ENTITY update(ENTITY entity);
  3. EntityModel<ENTITY> getById(Long id);
  4. ENTITY save(ENTITY entity);
  5. void delete(Long id);
  6. Collection<ENTITY> getAll();
  7. }
  8. public abstract class AbstractServiceImpl<ENTITY extends AbstractEntity> implements AbstractService<ENTITY> {
  9. protected abstract JpaRepository<ENTITY, Long> getRepository();
  10. @Override
  11. public Collection<ENTITY> getAll() {
  12. return getRepository().findAll();
  13. }
  14. @Override
  15. public EntityModel<ENTITY> getById(Long id) {
  16. return EntityModel.of(getRepository().getOne(id));
  17. }
  18. }
  19. @Service
  20. public class UserServiceImpl extends AbstractServiceImpl<User> implements UserService {
  21. private final UserRepository userRepository;
  22. @Override
  23. protected JpaRepository<User, Long> getRepository() {
  24. return userRepository;
  25. }
  26. }
  • resource 包
  1. public abstract class AbstractResource<ENTITY extends AbstractEntity>{
  2. public abstract AbstractService<ENTITY> getService();
  3. @GetMapping(value = "/{id}", produces = {"application/hal+json"})
  4. public EntityModel<ENTITY> getById(@PathVariable("id") Long id) {
  5. return getService().getById(id);
  6. }
  7. @GetMapping
  8. public Collection<ENTITY> getAll() {
  9. return getService().getAll();
  10. }
  11. }

当我保持这样 - 一切正常工作 - 我按预期获得响应:

  1. @RestController
  2. @RequestMapping("/api/users")
  3. public class UserResource extends AbstractResource<User> {
  4. @Autowired
  5. private final UserService userService;
  6. @Override
  7. public AbstractService<User> getService() {
  8. return userService;
  9. }
  10. }

当我尝试覆盖此方法时,出现错误:

  1. @RestController
  2. @RequestMapping("/api/users")
  3. public class UserResource extends AbstractResource<User> {
  4. @Autowired
  5. private final UserService userService;
  6. @Override
  7. public AbstractService<User> getService() {
  8. return userService;
  9. }
  10. @Override
  11. public EntityModel<User> getById(Long id) {
  12. return userService.getById(id);
  13. return super.getById(id);
  14. }
  15. }
英文:

I want to add spring-hateoas to my portfolio project and make it fully restful. That means that I need to override methods given by AbstractResource class(this is base class for my @RestController's) to edit it for my needs and when I do so I get org.springframework.dao.InvalidDataAccessApiUsageException: The given id must not be null!

My project look as follows:

  • service package
  1. public interface AbstractService&lt;ENTITY extends AbstractEntity&gt; {
  2. ENTITY update(ENTITY entity);
  3. EntityModel&lt;ENTITY&gt; getById(Long id);
  4. ENTITY save(ENTITY entity);
  5. void delete(Long id);
  6. Collection&lt;ENTITY&gt; getAll();
  7. }
  8. public abstract class AbstractServiceImpl&lt;ENTITY extends AbstractEntity&gt; implements AbstractService&lt;ENTITY&gt; {
  9. protected abstract JpaRepository&lt;ENTITY, Long&gt; getRepository();
  10. @Override
  11. public Collection&lt;ENTITY&gt; getAll() {
  12. return getRepository().findAll();
  13. }
  14. @Override
  15. public EntityModel&lt;ENTITY&gt; getById(Long id) {
  16. return EntityModel.of(getRepository().getOne(id));
  17. }
  18. }
  19. @Service
  20. public class UserServiceImpl extends AbstractServiceImpl&lt;User&gt; implements UserService {
  21. private final UserRepository userRepository;
  22. @Override
  23. protected JpaRepository&lt;User, Long&gt; getRepository() {
  24. return userRepository;
  25. }
  26. }
  • resource package
  1. public abstract class AbstractResource&lt;ENTITY extends AbstractEntity&gt;{
  2. public abstract AbstractService&lt;ENTITY&gt; getService();
  3. @GetMapping(value = &quot;/{id}&quot;, produces = {&quot;application/hal+json&quot;})
  4. public EntityModel&lt;ENTITY&gt; getById(@PathVariable(&quot;id&quot;) Long id) {
  5. return getService().getById(id);
  6. }
  7. @GetMapping
  8. public Collection&lt;ENTITY&gt; getAll() {
  9. return getService().getAll();
  10. }
  11. }

When I leave this like so - everything works normal - I get responses as expected

  1. @RestController
  2. @RequestMapping(&quot;/api/users&quot;)
  3. public class UserResource extends AbstractResource&lt;User&gt; {
  4. @Autowired
  5. private final UserService userService;
  6. @Override
  7. public AbstractService&lt;User&gt; getService() {
  8. return userService;
  9. }
  10. }

Error ocurrs when I try to override this method

  1. @RestController
  2. @RequestMapping(&quot;/api/users&quot;)
  3. public class UserResource extends AbstractResource&lt;User&gt; {
  4. @Autowired
  5. private final UserService userService;
  6. @Override
  7. public AbstractService&lt;User&gt; getService() {
  8. return userService;
  9. }
  10. @Override
  11. public EntityModel&lt;User&gt; getById(Long id) {
  12. return userService.getById(id);
  13. or
  14. return super.getById(id);
  15. }
  16. }

答案1

得分: 0

UserResource覆盖AbstractResource.getById(Long)之后,尽管@GetMapping(value = "/{id}", produces = {"application/hal+json"})注解是继承的,但@PathVariable("id")注解却没有被继承。将@PathVariable("id")注解放在UserResource.getById(Long)内部应该可以解决你的问题。

强烈建议在Github上放置一个可运行的示例项目(包括请求URL和测试数据),以重现你遇到的错误。否则,很难找出错误的原因并进行验证。

英文:

After UserResource overrides AbstractResource.getById(Long), though the annotation @GetMapping(value = &quot;/{id}&quot;, produces = {&quot;application/hal+json&quot;}) is inherited, the annotation @PathVariable(&quot;id&quot;) is not. Put the annotation @PathVariable(&quot;id&quot;) within UserResource.getById(Long) should solve your problem.

It's highly recommended to put a runnable sample project (including request URL and test data) in Github to reproduce the error you encountered. Otherwise, it's difficult to find out the cause and verify.

huangapple
  • 本文由 发表于 2020年8月17日 05:31:19
  • 转载请务必保留本文链接:https://go.coder-hub.com/63442129.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定