Hibernate EntityManager como evitar marked as rollback com registros lockados

0 respostas
ronaldocwb

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!

Criado 18 de maio de 2010
Respostas 0
Participantes 1