Capturando excessões utilizando método @Transactional

Olá venho por meio deste mais uma vez abrir um tópico para a anotação @Transactional, o projeto utiliza Hibernate + Spring. O projeto possui Persistencia Generica, o problema começou quando resolvi colocar a anotação @Transactional no negocio levando em conta que preciso fazer várias transações em apenas 1 método então preciso do rollback caso aconteça QUALQUER exception. Só que ao contrário do que eu imaginava o projeto simplesmente parou de capturar as exceptions enviando a exeption para a view, segue abaixo o codigo do método do negócio:

	@Override
	@Transactional(propagation=Propagation.REQUIRES_NEW, rollbackFor={Exception.class, DataIntegrityViolationException.class, ConstraintViolationException.class})
	public ArrayList<?> salvar(Cidade e) {
		try {
			objDao.salvar(e);
			arrRet = new ArrayList();
			arrRet.add(0, 1);
			arrRet.add(1, Mensagens.getMensagem(1));
			return arrRet;
		} catch (Exception ex) {
			return TrataException.TratarException(ex);
		}
	}

Segue abaixo o codigo da persistencia generica

	public synchronized E salvar(E entity) throws Exception, DataIntegrityViolationException, ConstraintViolationException {
		if (!getEntityManager().contains(entity))
			entity = getEntityManager().merge(entity);
		getEntityManager().persist(entity);
		return entity;
	}

Bem simples né… eu gostaria de saber se é possivel tratar qualquer exeption que aconteça… Pelo o que da para ver a transação fica aberta até o return, quando ele executa o return ele vai fechar a transação e os possíveis commits, então se der exeption é tratada pela camada de cima, então ja até averiguei de fazer mais uma camada so para poder tratar a exeption. Me deem uma luz por favor. segue abaixo a exeption que vai para o cliente

org.springframework.dao.DataIntegrityViolationException : Could not execute JDBC batch update; SQL [insert into public.cidade (cida_nome, cida_uf, empe_id, usua_id, cida_id) values (?, ?, ?, ?, ?)]; constraint [null]; nested exception is org.hibernate.exception.ConstraintViolationException: Could not execute JDBC batch update

A propósito, esta exeption é gerada por que o campo cida_nome é unique no banco, então estou tentando cadastrar uma cidade que ja existe no banco. Fico no aguardo pessoal. Muito obrigado

Eu não entendi ao certo o que você quer fazer, mas vamos lá. O @Transactional do Spring, serve por exemplo (entre outras coisas), para você evitar essa duplicação de código:

try {
      connection.beginTransaction();
      // SUA OPERAÇÃO AQUI. 
      connection.commit();
} catch (Exception e) {
      //deu erro ? seu codigo roolback entraria aqui
      connection.rollback();
} finally {
      connection.close();
}

claro, vai muito mais além disso, isso foi só um exemplo básico.

Você fazendo:

@Transactional(propagation=Propagation.REQUIRES_NEW, rollbackFor={Exception.class, DataIntegrityViolationException.class,

você está dizendo para o Spring que SE aquele metodo lançar uma das execptions de rollbackFor={Exception.class, DataIntegrityViolationException.class, ConstraintViolationException.class} (Só de você colocar Exception.class, as outras classes creio que já ficam redundantes [teste, pois faz tempo que não uso este recurso específico])

propagation=Propagation.REQUIRES_NEW = “SEMPRE rodar esta transação em uma transação separada”, ou seja, se você chamar este metodo dentro de uma transação já existente, ele cria uma transação filha, e caso esse filha de exception e você faça um catch na transação pai, só será feito roolback na filha, conversando a transação pai.

Lembre-se também que a transação inicia no começo do metodo, e termina na final do metodo.

Olá WRYEL obrigado por responder, o problema não é as informações sobre o transactional e sim sobre o por que depois de colocar a anotação @Transactional o método “parou” de entrar no } catch (Exception ex) { , ele simplesmente executa o bloco do try sem problema e da o return, só que chega uma excessão na camada de visualização, a idéia é tratar qualquer exeption que aconteça neste método por isso coloquei o } catch (Exception ex) {, mas ele simplesmente ignora, é como se não tivesse o try/catch