У меня есть аспект методов в транзакционной службе. К сожалению, когда я ловлю ошибки службой, выбрасывается другое исключение. Как я могу предотвратить эту ошибку? * Я искал аналогичный вопрос, но ни одно решение не подходит для моего случая.
@Aspect
@Component
public class ServiceGuard {
@Pointcut("execution(* simgenealogy.service.*.*(..))")
public void persistence() {}
@Around("persistence()")
public Object logPersistence(ProceedingJoinPoint joinPoint) {
try {
Object o = joinPoint.proceed();
return o;
} catch (ConstraintViolationException constraintException) {
// (...)
return null;
} catch (Throwable throwable) {
// (...)
return null;
}
}
}
И журнал ошибок.
2019-07-29 02:10:37.979 ERROR 11300 --- [ion Thread] s.a.g.s.w.ServiceGuard :
Constraint violation: First Name cannot be empty
2019-07-29 02:10:38.023 ERROR 11300 --- [ion Thread] s.a.g.s.w.ServiceGuard :
Constraint violation: Last Name cannot by empty
Exception in thread "JavaFX Application Thread" org.springframework.transaction.UnexpectedRollbackException: Transaction silently rolled back because it has been marked as rollback-only
at org.springframework.transaction.support.AbstractPlatformTransactionManager.processCommit(AbstractPlatformTransactionManager.java:755)
at org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:714)
at org.springframework.transaction.interceptor.TransactionAspectSupport.commitTransactionAfterReturning(TransactionAspectSupport.java:534)
at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:305)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:98)
at

Вы ловите исключения, которые, вероятно, возникают по какой-то причине. Затем вы просто возвращаете null как результат ранее выполненного (через proceed()) метода, возможно, в ситуациях, когда ожидается другое, ненулевое возвращаемое значение.
Поскольку вы не предоставляете никакого кода приложения, это спекулятивно, но я предполагаю, что возвращаемое значение null затем присваивается свойству данных, которое должно иметь ненулевое значение (см. нарушения ограничений в вашем журнале). Точнее, вы устанавливаете для имени и фамилии значение null, что приводит к нарушению ограничений, что, в свою очередь, приводит к откату вашей транзакции, поскольку обязательные поля данных не установлены.
Как это исправить? Либо возвращайте ненулевые значения по умолчанию для имени/фамилии (хотя звучит странно), либо допускайте эскалацию исходных исключений вместо того, чтобы поглощать их и вызывать последующие проблемы.
Итог: ваша обработка исключений просто сломана и нуждается в исправлении.
Ваш ответ меня удивляет, но как бы то ни было, в этом случае я запрашиваю MCVE на GitHub, воспроизводя проблему. Аспект без приложения, в который он вплетается, лог с ошибками, которые не являются ошибками, определенно недостаточны для того, чтобы я мог вам помочь.
Хорошо, я нашел решение. @Transactional также является аспектом @Arround. Проблема заключалась в упорядочении аспектов. Мой класс Guard на самом деле не был связан с Transaction. Поместите @Order(0) в состояние Guard и @Order(1) в службу @Transactional, решенную проблему.
Я возвращаю null, потому что я хотел бы передать это значение в Facade Layer, если возникнет какая-либо ошибка. Это правильное возвращаемое значение. Constraint Error в моем тестовом примере в порядке. Третья ошибка не в порядке. Если я перенесу свой аспект на слой фасада, все будет в порядке.