Seguinte, estou desenvolvendo uma aplicação em que a transação (JTA) é mantida durante todo um processo de manutenção de um Mestre Detalhe. Pela especificação JPA o EntityManager sempre marca a transação como RollBackOnly no caso de alguma exceção ocorrer. O problema que estou enfrentando é que na listagem de detalhes de uma tela algum registro pode estar lockado no banco de dados, isso para mim é uma exception tratavel, mas o hibernate marca minha transação como RollBackOnly devido a exception lançada. Eu não consigo apenas checar se o registro está com lock antes de tentar fazer o meu lock, assim sempre vai acabar lançando a exception.
Precisava de uma forma de interceptar esse tratamento do erro para evitar essa marcação. Alguma idéia?
Abaixo o método que o hibernate utiliza para tratar as exceptions:
public void throwPersistenceException(HibernateException e) {
if ( e instanceof StaleStateException ) {
PersistenceException pe = wrapStaleStateException( (StaleStateException) e );
throwPersistenceException( pe );
}
else if ( e instanceof ObjectNotFoundException ) {
throwPersistenceException( new EntityNotFoundException( e.getMessage() ) );
}
else if ( e instanceof org.hibernate.NonUniqueResultException ) {
throwPersistenceException( new NonUniqueResultException( e.getMessage() ) );
}
else if ( e instanceof UnresolvableObjectException ) {
throwPersistenceException( new EntityNotFoundException( e.getMessage() ) );
}
else if ( e instanceof QueryException ) {
throw new IllegalArgumentException( e );
}
else if ( e instanceof TransientObjectException ) {
try {
markAsRollback();
}
catch (Exception ne) {
//we do not want the subsequent exception to swallow the original one
log.error( "Unable to mark for rollback on TransientObjectException: ", ne);
}
throw new IllegalStateException( e ); //Spec 3.2.3 Synchronization rules
}
else {
throwPersistenceException( new PersistenceException( e ) );
}
}
public void throwPersistenceException(PersistenceException e) {
if ( ! ( e instanceof NoResultException || e instanceof NonUniqueResultException ) ) {
try {
markAsRollback();
}
catch (Exception ne) {
//we do not want the subsequent exception to swallow the original one
log.error( "Unable to mark for rollback on PersistenceException: ", ne);
}
}
throw e;
}
Minha ultima opção seria gerar uma versão personalizada do HibernateEntityManager para minha aplicação, colocando mais uma condição nesse metodo caso a exception seja LockAcquisitionException.
Toda ajuda é válida!