spring:entitymanager和spring存储库是否在同一上下文中工作?

uemypmqf  于 2021-07-11  发布在  Java
关注(0)|答案(0)|浏览(255)

我有两个实体:

  1. class Checkbook{
  2. ...
  3. private int canceledChecks;
  4. ...
  5. }

  1. class Check{
  2. ...
  3. @ManyToOne
  4. private Checkbook checkbook;
  5. private int status;
  6. ...
  7. }

我想增加 canceledChecksCheckbook 实体 Check 已取消 (status become 1) ,因此我创建了一个事件侦听器,如下所示:

  1. @Component
  2. public class CheckChangeListener implements PreUpdateEventListener {
  3. @PersistenceContext
  4. private EntityManager em;
  5. @Override
  6. public boolean onPreUpdate(PreUpdateEvent event) {
  7. if(event.getEntity() instanceof Check){
  8. Check check = (Check)event.getEntity();
  9. CheckBook checkbook = check.getCheckBook();
  10. int oldStatus = getStatusFromEntityState(event.getOldState(), event);
  11. int newStatus = getStatusFromEntityState(event.getState(), event);
  12. if(oldStatus != newStatus && newStatus = 1){//means check is updated and canceled
  13. checkbook.setCanceledChecks(checkbook.getCanceledChecks() + 1);
  14. em.persist(checkbook); // persist new checkbook changes
  15. }
  16. }
  17. return false;
  18. }
  19. private int getStatusFromEntityState(Object[] state, PreUpdateEvent event){
  20. String[] properties = event.getPersister().getEntityMetamodel().getPropertyNames();
  21. int pos = -1;
  22. for (int i = 0; i < properties.length; i++) {
  23. if(properties[i].equals("status")) pos = i;
  24. }
  25. return (Integer)state[pos];
  26. }

现在在 CheckController :

  1. @RestController
  2. @RequestMapping("/api/check")
  3. public class CheckController {
  4. @Autowired
  5. private CheckRepository repository;
  6. @PutMapping("/{id}/cancel")
  7. public ResponseEntity<Check> cancel(@PathVariable Long id) throws NotFoundException {
  8. Check check = repository.findById(id)
  9. .orElseThrow(() -> new NotFoundException("Check with id "+id+" not found!"));
  10. check.setStatus(1);
  11. repository.save(check);
  12. return ResponseEntity.status(HttpStatus.ACCEPTED).body(check);
  13. }
  14. }

现在奇怪的是,监听器正在被调用,但是checkbook没有更新。
但是,当我这样改变控制器时:

  1. @RestController
  2. @RequestMapping("/api/check")
  3. public class CheckController {
  4. @Autowired
  5. private CheckRepository repository;
  6. @PersistenceContext
  7. private EntityManager em;
  8. @Transactional
  9. @PutMapping("/{id}/cancel")
  10. public ResponseEntity<Check> cancel(@PathVariable Long id) throws NotFoundException {
  11. Check check = repository.findById(id)
  12. .orElseThrow(() -> new NotFoundException("Check with id "+id+" not found!"));
  13. check.setStatus(1);
  14. em.persist(check);
  15. em.flush();
  16. return ResponseEntity.status(HttpStatus.ACCEPTED).body(check);
  17. }
  18. }

现在它工作了 Check 正在随 Checkbook !! 我以为 Spring data JPA 在与 EntityManager ,我说的对吗?
我来自一个 Symfony 我们只有 EntityManager 所以第二个场景对我来说更有意义(尽管我必须添加 @Transactional 注解以使其工作)
为什么第二种情况有效而第一种情况无效?!

暂无答案!

目前还没有任何答案,快来回答吧!

相关问题