未捕获由lambda引发的Java未经检查的异常

时间:2019-06-15 00:39:17

标签: java jpa transactions

我有一个函数,需要两个lambda作为参数。这些函数引发了一个我希望函数捕获的特定的未经检查的异常:

    /**
     *
     * @param insert function to insert the entity
     * @param fetch function to fetch the entity
     * @param <T> type of entity being inserted
     * @return
     */
    @Transactional(propagation = Propagation.REQUIRES_NEW, isolation = Isolation.READ_COMMITTED)
    public <T> T getOrInsertWithUniqueConstraints(Supplier<Optional<T>> fetch, Supplier<T> insert) {
        try {
            Optional<T> entity = fetch.get();
            T insertedEntity = entity.orElseGet(insert);
            return insertedEntity;
        }
        catch (Exception e){
            //I expect/want the exception to be caught here, 
            //but this code is never called when debugging
            Optional<T> entityAlreadyInserted = fetch.get();
            return entityAlreadyInserted.get();
        }
    }

在属于另一个事务的函数中调用哪个:

@Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
...
try {
    Player persistedPlayer = insertOrGetUtil.getOrInsertWithUniqueConstraints(
        () -> playerRepository.findOne(newPlayer.getUsername()),
        //this lambda throws the unchecked DataIntegrityViolationException
        () -> playerRepository.save(newPlayer)
    );
}
catch (Exception e){
    //the exception is caught here for some reason...
}

我误解了Java lambda的工作原理吗?同样值得注意的是,代码使用的是Spring的@TransactionalCrudRepository

1 个答案:

答案 0 :(得分:0)

在提交事务时实际上发生了异常,该异常在方法返回之后发生。为了解决这个问题,我使用了arrayList.stream() .reduce(Integer::max) .get() 来触发在方法返回之前提交时发生的任何异常:

EntityManager#flush()