[英]Java unchecked exception thrown by lambda is not caught
I have a function that takes two lambdas as a parameters. 我有一个函数,它将两个lambda作为参数。 These functions throw a specific unchecked exception that I want the function to catch:
这些函数抛出一个我想要函数捕获的特定未经检查的异常:
/**
*
* @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();
}
}
Which is called in a function belonging to another transaction: 在属于另一个事务的函数中调用它:
@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...
}
Am I misunderstanding how Java lambdas work? 我误解了Java lambdas是如何工作的吗? Also worth noting is the code is using Spring's
@Transactional
and CrudRepository
另外值得注意的是代码使用的是Spring的
@Transactional
和CrudRepository
The exception is actually happening while the transaction is being committed, which occurs after the method returns. 事务正在提交时实际发生异常,该异常在方法返回后发生。 To get around this, I used
EntityManager#flush()
to trigger any exceptions that would happen on commit before the method returns: 为了解决这个问题,我使用了
EntityManager#flush()
来触发在方法返回之前在提交时发生的任何异常:
@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);
entityManager.flush();
return insertedEntity;
}
catch (PersistenceException e){
DataAccessException dae = persistenceExceptionTranslator.translateExceptionIfPossible(e);
if (dae instanceof DataIntegrityViolationException){
Optional<T> entityAlreadyInserted = fetch.get();
return entityAlreadyInserted.get();
}
else {
throw e;
}
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.