ERRO: detached entity passed to persist

Durante o desenvolvendo um projeto pessoal me deparei com este erro, que indicava que uma entidade
detached estava sendo passada para um método de inclusão:

javax.persistence.PersistenceException: org.hibernate.PersistentObjectException: detached entity passed to persist: model.Criterio

O método em questão salvava, na verdade, uma entidade de outra classe:

Chave chave = new Chave();
chave.setNome(nomeChave);
chave.setPeso(new BigDecimal(pesoChave));
chave.setCriterioCollection(new ArrayList<Criterio>()); 

for(Criterio c : getCriteriosChave()){
 c.setCodChave(chave);
 chave.getCriterioCollection().add(c);
}

getBusinessDelegate().cadastrar(chave);

Tudo indicava que as entidades da classe Criterio, passadas à coleção da classe sendo salva, estavam vindo do banco de dados,
através de um gerenciador de persistência, mas não era este o caso. As entidades retornadas pelo método getCriteriosChave(),
neste caso, são criadas no momento da população da tela, ou seja, não são retornadas do banco.
Durante algum tempo bati cabeça, tentando entender o porquê deste erro, até que em um post encontrei uma dica que foi valiosa:
o identificador do objeto em questão, estava associado a um componente de tela:

<rich:column>
 <h:inputHidden id="hdncodigoCriterio" value="#{criterio.codigo}"/>
 <h:inputText id="txtNomeChave" required="true"
 disabled="#{!configuracaoGuiaBean.habilitarModificacoesChave}" 
 value="#{criterio.descricao}" size="100" maxlength="60">
 <f:validateLength minimum="5" maximum="60"/>
 </h:inputText>
 </rich:column>

Como isso pode influenciar no erro?
Ao associar o identificador da entidade a um componente de tela, o valor do mesmo, quando não atribuído explicitamente, será zero, e não nulo.
O gerenciador de persistência entenderá esse valor como sendo um identificador válido, como se a entidade tivesse sido obtida do banco de dados.
Para resolver o problema, bastou fazer um teste antes do momento da atribuição: se o valor do identificador for zero, o que indica
uma nova entidade, atribui-se nulo para seu valor:


for(Criterio c : getCriteriosChave()){
 c.setCodigo(c.getCodigo() == 0 ? null : c.getCodigo());
 c.setCodChave(chave);
 chave.getCriterioCollection().add(c);
}

Está dada a dica!

9 comentários sobre “ERRO: detached entity passed to persist

  1. Amigoo, caiu como um luva depois de passa 1 dia inteiro conseguir resolver o problema, Obrigado pela dica e foi mais que obrigação posta o meu comentario abraçoss

  2. Amigo o meu esta dando o mesmo problema e não consegui resolver. Pode me dar uma ajuda ?

    protected void processRequest(HttpServletRequest request, HttpServletResponse response)
    throws ServletException, IOException, ParseException {
    response.setContentType(“text/html;charset=UTF-8”);
    try (PrintWriter out = response.getWriter()) {

    HttpSession session = request.getSession();

    String nome = request.getParameter(“nome”);
    formatte = new SimpleDateFormat(“dd/MM/yyyy”);
    String stringDataNascimento = request.getParameter(“dataNascimento”);

    dataNascimentoConvertida = (Date) formatte.parse(stringDataNascimento);

    String cpf = request.getParameter(“cpf”);
    String rg = request.getParameter(“rg”);
    String telefone = request.getParameter(“telefone”);
    String endereco = request.getParameter(“endereco”);
    String cnh = request.getParameter(“cpf”);

    cliente.setId(cliente.getId() == 0 ? null : cliente.getId());
    cliente.setNome(nome);
    cliente.setDataNascimento(dataNascimentoConvertida);
    cliente.setCpf(cpf);
    cliente.setRg(rg);
    cliente.setTelefone(telefone);
    cliente.setEndereco(endereco);
    cliente.setCnh(cnh);

    EntityManager em = JpaUtil.getEntityManager();

    DaoFactory daoFactory = new DaoFactory(em);

    daoFactory.getCliente().addOrUpd(cliente);

    response.sendRedirect(“consultarclientes.jsp”);

    }

Deixe uma resposta

Preencha os seus dados abaixo ou clique em um ícone para log in:

Logotipo do WordPress.com

Você está comentando utilizando sua conta WordPress.com. Sair / Alterar )

Imagem do Twitter

Você está comentando utilizando sua conta Twitter. Sair / Alterar )

Foto do Facebook

Você está comentando utilizando sua conta Facebook. Sair / Alterar )

Foto do Google+

Você está comentando utilizando sua conta Google+. Sair / Alterar )

Conectando a %s