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

Java 如何使用@Transactional读取spring方法中保存的实例,java,spring-boot,transactions,rollback,Java,Spring Boot,Transactions,Rollback,我使用@Transactional注释进行回滚,我在我的Spring Boot应用程序中添加了控制器方法,因此我的保存只会在所有事情都发生且没有任何错误时发生,我就是这样添加注释的: @PostMapping(value = "/add/people") @Transactional public ResponseEntity<?> addGroundToPerson(@RequestParam("ground") String newGround, @Req

我使用
@Transactional
注释进行回滚,我在我的Spring Boot应用程序中添加了控制器方法,因此我的保存只会在所有事情都发生且没有任何错误时发生,我就是这样添加注释的:

    @PostMapping(value = "/add/people")
    @Transactional
    public ResponseEntity<?> addGroundToPerson(@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);
    }
RegisterAddress被调用了两次,第一次可以正常工作,但是因为我第一次保存了,所以第二次不能工作。(请记住,我的代码要比这个代码大得多,我不能就这么省钱,我已经试过了,相信我)

我尝试将@Transactional放入服务层,但它向我发送了以下错误:

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

当我只保存对象时,它可以正常工作,但当我必须在保存对象后获取对象时,它就不能正常工作。这就是我的问题,我最好的例子是:

  • 我每个人都有一个地址,上面写着州
  • 如果每个地址相同,我想对其重复使用状态
  • 我注册了一个人,它注册了一个新地址(有时使用数据库中已经存在的状态)
  • 我尝试注册地面,当我尝试使该状态重新使用时,我得到一个错误: 嵌套异常为org.hibernate.TransactionException:Transaction 仅标记为回滚;不能承诺


  • 我认为这是因为当我第一次“保存”对象时,它没有提交,所以它保持瞬态,而我就是无法获得瞬态对象。我正在尝试创建所有逻辑并在结尾保存,或者在出现异常时回滚,但由于注释的原因,我得到了这个错误。

    这个错误太多了。让我从您将
    @Transactional
    放在控制器层而不是服务层的事实开始。方法的逻辑也应该在服务层中。这个-
    rollboor=Exception.class
    实际上并不是必需的,因为Spring默认将
    rollboor={RuntimeException.class,Error.class}
    放在所有用
    @Transactional
    注释的方法上。现在,您得到提到的异常的原因是您在其中放置了一个try/catch块。只有当抛出异常时,Spring的事务才会标记为回滚,而不管它是否被捕获。您必须删除try/catch,或者在事务之外找到一种方法来执行它。

    这有很多问题。让我从您将
    @Transactional
    放在控制器层而不是服务层的事实开始。方法的逻辑也应该在服务层中。这个-
    rollboor=Exception.class
    实际上并不是必需的,因为Spring默认将
    rollboor={RuntimeException.class,Error.class}
    放在所有用
    @Transactional
    注释的方法上。现在,您得到提到的异常的原因是您在其中放置了一个try/catch块。只有当抛出异常时,Spring的事务才会标记为回滚,而不管它是否被捕获。您必须删除try/catch,或者找到一种在事务之外执行的方法。

    即使抛出错误,我也不会尝试提交这些节省,我的问题是,由于注释,我会收到该错误。您能显示失败的特定方法吗?很难从上面给出的几行中找出错误。也许现在它更有意义了,我已经添加了一些代码,但它并不完全是我所拥有的,但问题是,当你把它放在服务层时,它会抛出一个临时异常,因为你给了这个方法一个实体,而不是给它一个id,然后在这个事务中从数据库中获取实体。我猜你在
    searchState()
    中抛出了
    NoSuchElementException
    ,这意味着你的get方法不起作用,或者你保存
    状态的方法不起作用。即使抛出了错误,我也不会尝试提交这些节省,我的问题是,由于注释的原因,我得到了那个错误。您能显示失败的具体方法吗?很难从上面给出的几行中找出错误。也许现在它更有意义了,我已经添加了一些代码,但它并不完全是我所拥有的,但问题是,当你把它放在服务层时,它会抛出一个临时异常,因为你给了这个方法一个实体,而不是给它一个id,然后在这个事务中从数据库中获取实体。我猜你在
    searchState()
    中抛出了
    NoSuchElementException
    ,这意味着你的get方法不起作用,或者你保存
    状态的方法不起作用。
    
    public void registerAddress(HasAddress hasAddress) throws NoSuchElementException {
    
            Address address = hasAddress.getAddress());
            State state = address.getState();
    
            //here's where I'm getting the error
            State dbState = searchState(state); //stateRepository.getStateByName();
    
            address.setState(state);
            hasAddress.setAddress(address);
    
            addressRepository.save(address);
        }