英文:
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 包
public interface AbstractService<ENTITY extends AbstractEntity> {
ENTITY update(ENTITY entity);
EntityModel<ENTITY> getById(Long id);
ENTITY save(ENTITY entity);
void delete(Long id);
Collection<ENTITY> getAll();
}
public abstract class AbstractServiceImpl<ENTITY extends AbstractEntity> implements AbstractService<ENTITY> {
protected abstract JpaRepository<ENTITY, Long> getRepository();
@Override
public Collection<ENTITY> getAll() {
return getRepository().findAll();
}
@Override
public EntityModel<ENTITY> getById(Long id) {
return EntityModel.of(getRepository().getOne(id));
}
}
@Service
public class UserServiceImpl extends AbstractServiceImpl<User> implements UserService {
private final UserRepository userRepository;
@Override
protected JpaRepository<User, Long> getRepository() {
return userRepository;
}
}
- resource 包
public abstract class AbstractResource<ENTITY extends AbstractEntity>{
public abstract AbstractService<ENTITY> getService();
@GetMapping(value = "/{id}", produces = {"application/hal+json"})
public EntityModel<ENTITY> getById(@PathVariable("id") Long id) {
return getService().getById(id);
}
@GetMapping
public Collection<ENTITY> getAll() {
return getService().getAll();
}
}
当我保持这样 - 一切正常工作 - 我按预期获得响应:
@RestController
@RequestMapping("/api/users")
public class UserResource extends AbstractResource<User> {
@Autowired
private final UserService userService;
@Override
public AbstractService<User> getService() {
return userService;
}
}
当我尝试覆盖此方法时,出现错误:
@RestController
@RequestMapping("/api/users")
public class UserResource extends AbstractResource<User> {
@Autowired
private final UserService userService;
@Override
public AbstractService<User> getService() {
return userService;
}
@Override
public EntityModel<User> getById(Long id) {
return userService.getById(id);
或
return super.getById(id);
}
}
英文:
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
public interface AbstractService<ENTITY extends AbstractEntity> {
ENTITY update(ENTITY entity);
EntityModel<ENTITY> getById(Long id);
ENTITY save(ENTITY entity);
void delete(Long id);
Collection<ENTITY> getAll();
}
public abstract class AbstractServiceImpl<ENTITY extends AbstractEntity> implements AbstractService<ENTITY> {
protected abstract JpaRepository<ENTITY, Long> getRepository();
@Override
public Collection<ENTITY> getAll() {
return getRepository().findAll();
}
@Override
public EntityModel<ENTITY> getById(Long id) {
return EntityModel.of(getRepository().getOne(id));
}
}
@Service
public class UserServiceImpl extends AbstractServiceImpl<User> implements UserService {
private final UserRepository userRepository;
@Override
protected JpaRepository<User, Long> getRepository() {
return userRepository;
}
}
- resource package
public abstract class AbstractResource<ENTITY extends AbstractEntity>{
public abstract AbstractService<ENTITY> getService();
@GetMapping(value = "/{id}", produces = {"application/hal+json"})
public EntityModel<ENTITY> getById(@PathVariable("id") Long id) {
return getService().getById(id);
}
@GetMapping
public Collection<ENTITY> getAll() {
return getService().getAll();
}
}
When I leave this like so - everything works normal - I get responses as expected
@RestController
@RequestMapping("/api/users")
public class UserResource extends AbstractResource<User> {
@Autowired
private final UserService userService;
@Override
public AbstractService<User> getService() {
return userService;
}
}
Error ocurrs when I try to override this method
@RestController
@RequestMapping("/api/users")
public class UserResource extends AbstractResource<User> {
@Autowired
private final UserService userService;
@Override
public AbstractService<User> getService() {
return userService;
}
@Override
public EntityModel<User> getById(Long id) {
return userService.getById(id);
or
return super.getById(id);
}
}
答案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 = "/{id}", produces = {"application/hal+json"})
is inherited, the annotation @PathVariable("id")
is not. Put the annotation @PathVariable("id")
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.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论