Senhores,
considerando o modelo de classes em anexo, tenho uma página de inclusão do cliente. Lá o usuário tem a chance de “validar” um logradouro que ela escrever. Quando ele o faz, o banco de dados prepara o formulário preenchendo o endereço já existente se só existir um logradouro de acordo com o que foi procurado ou exibe uma lista caso contrário.
A questão é que, se o logradouro não está pré-cadastrado o usuário define o novo endereço na mesma página e as regras do negócio resolvem o problema. Mas se por acaso é digitado um bairro, logradouro ou cidade inexistente, estes também são inserido automaticamente.
Este é o código do JPA que trata a coisa:
[code] @Transactional(readOnly=false)
public void salvar(Cliente cliente){
RegiaoEndereco reCliente = cliente.getEndereco().getRegiaoEndereco();
TipoEndereco t = null;
t = bU.buscarTipoEndereco(reCliente.getTipoEndereco().getId());
Logradouro l = null;
try {
l = bU.buscarLogradouroExato(reCliente.getLogradouro().getNome());
em.merge(l);
} catch (NoResultException n){
l = new Logradouro();
l.setNome(reCliente.getLogradouro().getNome());
em.persist(l);
}
Bairro b = null;
try {
b = bU.buscarBairroExato(reCliente.getBairro().getNome());
em.merge(b);
} catch (NoResultException n){
b = new Bairro();
b.setNome(reCliente.getBairro().getNome());
em.persist(b);
}
Cidade cid;
try {
cid = bU.buscarCidadeExato(reCliente.getCidade().getNome());
em.merge(cid);
} catch (NoResultException n){
cid = new Cidade();
cid.setNome(reCliente.getCidade().getNome());
em.persist(cid);
}
// Desnecessário procurar estado, enquanto o software não sair do RJ (Eh, eh!).
Estado e = bU.buscarEstadoExato("RIO DE JANEIRO");
em.merge(e);
RegiaoEndereco re = new RegiaoEndereco(t, l, b, cid, e);
RegiaoEndereco reReal = null;
try {
reReal = bU.buscarRegioesEnderecosExato(re);
em.merge(reReal);
} catch (NoResultException n){
reReal = re;
em.persist(reReal);
}
cliente.getEndereco().setRegiaoEndereco(reReal);
if (cliente.getId() == null){
em.persist(cliente);
} else {
em.merge(cliente);
}
}
[/code]
Como uso o Struts2, uso a função de preenchimento de todo o gráfico do objeto. Por isso verifico se o logradouro, bairro e cidade já existem para incluí-los ou não.
Pois bem, depois de me alongar desse jeito, quando preciso incluir um dos valores (bairro, cidade, etc.) no código, é disparado o erro abaixo:
SEVERE: Servlet.service() for servlet default threw exception
javax.persistence.RollbackException: Transaction marked as rollbackOnly
at org.hibernate.ejb.TransactionImpl.commit(TransactionImpl.java:51)
at org.springframework.orm.jpa.JpaTransactionManager.doCommit(JpaTransactionManager.java:456)
at org.springframework.transaction.support.AbstractPlatformTransactionManager.processCommit(AbstractPlatformTransactionManager.java:709)
at org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:678)
at org.springframework.transaction.interceptor.TransactionAspectSupport.commitTransactionAfterReturning(TransactionAspectSupport.java:321)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:116)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:171)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:204)
at $Proxy24.salvar(Unknown Source)
at br.com.pizzaria.servico.ClientesServico.salvar(ClientesServico.java:32)
at br.com.pizzaria.acoes.ClientesCRUDAction.salvar(ClientesCRUDAction.java:40)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
Todo este gráfico está marcado com o CascadeType.ALL. Eu sei que o setRollbackOnly é disparado somente quando uma exceção não-checada é lançada. Mas no log não aparece nada! Existe alguma outra possibilidade da transação ser marcada para rollBackOnly()?
Alguém tem alguma pista?
Muito obrigado pela paciência e desculpem pelo testamento. Estou no desespero e não queria mudar muito a linha de raciocínio.