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

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

我有两个实体:

class Checkbook{
   ...
   private int canceledChecks;
   ...
}

class Check{
   ...
   @ManyToOne
   private Checkbook checkbook;

   private int status;
   ...
}

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

@Component
public class CheckChangeListener implements PreUpdateEventListener {

    @PersistenceContext
    private EntityManager em;

    @Override
    public boolean onPreUpdate(PreUpdateEvent event) {

        if(event.getEntity() instanceof Check){
            Check check = (Check)event.getEntity();
            CheckBook checkbook = check.getCheckBook();
            int oldStatus = getStatusFromEntityState(event.getOldState(), event);
            int newStatus = getStatusFromEntityState(event.getState(), event);

            if(oldStatus != newStatus && newStatus = 1){//means check is updated and canceled
                 checkbook.setCanceledChecks(checkbook.getCanceledChecks() + 1);
                 em.persist(checkbook); // persist new checkbook changes
            }
        }

        return false;
    }

    private int getStatusFromEntityState(Object[] state, PreUpdateEvent event){
        String[] properties = event.getPersister().getEntityMetamodel().getPropertyNames();
        int pos = -1;
        for (int i = 0; i < properties.length; i++) {
            if(properties[i].equals("status")) pos = i;
        }

        return (Integer)state[pos];
    }

现在在 CheckController :

@RestController
@RequestMapping("/api/check")
public class CheckController {

    @Autowired
    private CheckRepository repository;

    @PutMapping("/{id}/cancel")
    public ResponseEntity<Check> cancel(@PathVariable Long id) throws NotFoundException {
        Check check = repository.findById(id)
                .orElseThrow(() -> new NotFoundException("Check with id "+id+" not found!"));

        check.setStatus(1);

        repository.save(check);

        return ResponseEntity.status(HttpStatus.ACCEPTED).body(check);
    }
}

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

@RestController
@RequestMapping("/api/check")
public class CheckController {

    @Autowired
    private CheckRepository repository;

    @PersistenceContext
    private EntityManager em;

    @Transactional
    @PutMapping("/{id}/cancel")
    public ResponseEntity<Check> cancel(@PathVariable Long id) throws NotFoundException {
        Check check = repository.findById(id)
                .orElseThrow(() -> new NotFoundException("Check with id "+id+" not found!"));

        check.setStatus(1);

        em.persist(check);
        em.flush();

        return ResponseEntity.status(HttpStatus.ACCEPTED).body(check);
    }
}

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

暂无答案!

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

相关问题