如何使用@Transactional在spring方法中读取保存的实例

问题描述 投票:0回答:1

我正在使用@Transactional批注进行回滚,我已经在Spring-Boot应用程序中的控制器方法中添加了它,所以只有在一切都发生而没有任何错误的情况下,我的保存才会发生,这就是我添加的方式注释:

    @PostMapping(value = "/add/people")
    @Transactional
    public ResponseEntity<?> deletaLoteDoProcesso(@RequestParam("ground") String newGround, @RequestParam("person") String person {
        try {
             personService.addPerson(person, ground);
             Ground addedGround = groundService.addGround(pnewGround);
        } catch (NoSuchElementException e) {
            return new ResponseEntity<>(new CustomErrorType(e.getMessage()), HttpStatus.NOT_IMPLEMENTED);
    }

addPersonToGround正在将该人及其地址保存在数据库中。

addGround是使用该人引用保存数据库中的新地面的内容,并且地面本身具有地址。

我尝试将@Transactional放在服务层中,但它向我发送此错误:

org.hibernate.TransientPropertyValueException:对象引用了未保存的瞬态实例

仅保存对象时效果很好,但是保存后必须获取对象时效果不佳。那就是我的问题,我最好的例子是:

  1. 我每个人都有一个地址,并且里面有州。
  2. 如果地址相同,我想为每个地址重用状态。
  3. 我注册了一个人,并且注册了一个新地址(某些东西使用数据库中已经存在的状态)。
  4. 我尝试注册地面,当我尝试重新使用该状态时,出现错误:

    嵌套的异常是org.hibernate.TransactionException:事务被标记为仅回滚;无法提交

我认为是因为我第一次“保存”对象时它没有提交,所以它保持瞬态状态,而我却无法获得瞬态对象。我正在尝试制作所有逻辑并在其末尾进行保存,如果发生某些异常,则进行回滚,但是由于注释,我遇到了该错误。

java spring-boot transactions rollback
1个回答
2
投票
太多错误了。首先,我将@Transactional放在控制器层而不是服务层中。方法的逻辑也应该在Service层中。这个-rollbackFor = Exception.class并不是必须的,因为默认情况下,Spring在所有带有rollbackFor = { RuntimeException.class, Error.class }注释的方法上都放置@Transactional。现在,出现上述异常的原因是因为您在其中放置了try / catch块。仅当抛出异常(无论是否捕获)时,Spring的事务才被标记为回滚。您必须删除try / catch或找到一种在事务之外进行操作的方法。
© www.soinside.com 2019 - 2024. All rights reserved.