2007-10-29 16:54:43,218 ERROR hibernate.util.JDBCExceptionReporter -> Cannot delete or update a parent row: a foreign key constraint fails (`exemplo/perfil`, CONSTRAINT `FKC4E369CC301860CE` FOREIGN KEY (`unidade_id`) REFERENCES `unidade` (`unidade_id`))
2007-10-29 16:54:43,218 ERROR event.def.AbstractFlushingEventListener -> Could not synchronize database state with session
org.hibernate.exception.ConstraintViolationException: Could not execute JDBC batch update
at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:71)
Como posso tratar isto? Pois ao executar o meu método delete, ele não passa no catch…
Alguém pode me dar uma dica?
Certo, no caso eu tenho que passar o objeto detached para o estado persistente.
Tentei fazer isso por meiodo método merge do entityManager, mas não mudou nada, o mesmo erro continua.
Você sabe o que eu posso estar fazendo de errado? :?
Não tem como eu recuperar este erro para tratá-lo? Pois gostaria de exibir uma tela dizendo que não foi possivel excluir a unidade, já que ela está associada a um perfil.
Estou te mandando o meu delete para vc dar uma olhada:
/**
* Remove o objeto da session.
* @param obj Objeto passado como parâmetro, que extenda T.
*/
public void remove (T obj) {
logger.debug("removing" + obj + " " + this.clazz);
/**
* Carrega um novo objeto para não ter problema, já existe um outro objeto
* managed com o mesmo id na Session,
*/
T objetoManaged = this.procura((Long) this.getId(obj, this.clazz));
this.session.delete(objetoManaged);
}
Método procura:
/**
* Busca um objeto pelo id passado como parâmetro.
* @param id Long.
* @return T Objeto.
* @throws org.hibernate.HibernateException
*/
@SuppressWarnings("unchecked")
public T procura(Long id) throws org.hibernate.HibernateException{
logger.debug("searching " + this.clazz.getName() + " for " + id);
return (T) session.load(this.clazz, id);
}
Método getId:
/**
* Buscar o campo 'id' do objeto passado como argumento.
* @param val Objeto.
* @param classe
* @return Id.
*/
private Object getId(Object val, Class<? extends Object> classe) {
try {
return classe.getMethod("getId").invoke(val);
} catch (IllegalArgumentException e) {
logger.error("Erro ao invocar id - IllegalArgumentException: ", e);
} catch (SecurityException e) {
logger.error("Erro ao invocar id - SecurityException: ", e);
} catch (IllegalAccessException e) {
logger.error("Erro ao invocar id - IllegalAccessException: ", e);
} catch (InvocationTargetException e) {
logger.error("Erro ao invocar id - InvocationTargetException: ", e);
} catch (NoSuchMethodException e) {
logger.error("Erro ao invocar id - NoSuchMethodException: ", e);
}
return null;
}
Em relação a mensagem de erro que você vai exibir, trate isso na sua lógica!
Muito obrigada pelo exemplo de delete que você me enviou!
Bom, o erro persiste…
Quando eu tento remover uma unidade que não está relacionada a nenhum perfil, ele consegue efetuar o delete normalmente , já quando eu tento deleter uma que está associada a um perfil, ele dá a ConstraintViolationException, está certo, eu sei que uma violação de chave está sendo feita, mas eu gostaria de saber como pegá-la e tratá-la para poder exibir uma mensagem, e não aparecer aquela tela de erro Apache/ Tomcat… :?
Porque o que acontece é o seguinte: quando ocorre a violação, ele passa pele delete, entra no try e não sai…
Antes de remover a Unidade de um "load" nela, neste codigo voce nao esta fazendo isso
faltou uma linha ai fazendo um findById(Integer id);
public boolean delete(Unidade unidade) {
try {
unidade = unidadeDAO.findById( unidade.getId() ); //caso nao tenha o id use um "findByName( unidade.getNome() );"
entityManager.remove( unidade );
return true; // Ele acaba passando aqui!
} catch (Exception ex) {
getFacesContext().addMessage(null,new FacesMessage(ex.getMessage()));
UnidadeDAO.log.error(ex);
return false;
}
}
Uma exceção como o proprio nome diz é uma "excessao a regra" algo fora do comun aconteceu.
Tens que pesquisar a unidade e com alguma regra você conferir se pode excluir ela ou não.
Não conheco a modelagem mas supondo um caso simples, você nao pode excluir uma unidade
caso tenha Usuarios vinculados a ela. Entao antes de remover a unidade você deve fazer um "load"
na unidade e conferir se a List<Usuario> esta vazia… pegou a ideia ?
1. 2007-10-29 16:54:43,218 ERROR hibernate.util.JDBCExceptionReporter -> Cannot delete or update a parent row: a foreign key constraint fails (`exemplo/perfil`, CONSTRAINT `FKC4E369CC301860CE` FOREIGN KEY (`unidade_id`) REFERENCES `unidade` (`unidade_id`))
2. 2007-10-29 16:54:43,218 ERROR event.def.AbstractFlushingEventListener -> Could not synchronize database state with session
3. org.hibernate.exception.ConstraintViolationException: Could not execute JDBC batch update
4. at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:71)