AnswerBun.com

Persistir objeto em CRUD JSF + CDI + JPA

Stack Overflow em Português Asked by Gleison on October 14, 2020

Estou fazendo um CRUD simples, usando JSF, JPA e CDI.

Tenho duas telas:

  • Uma tela com um datatable listando os dados, em cada linha tem o botão editar e excluir, no inicio da tela tem um botão inserir, os boões editar e inserir direcionam para a segunda tela.
  • A segunda tela é o formulário, com os inputs e o botão de salvar

Tenho um bean ViewScoped para cuidar de ambas telas e passo os parâmetros de uma tela para a outra com o f:setPropertyActionListener, tudo funciona de acordo, tanto o inserir quanto o editar.

Agora quando o bean ao validar alguma regra de negócio impede o usuário de editar (neste caso retornando null ao action do botão), a tela volta para o usuário corrigir o dado e submeter novamente, mas quando isso acontece o meu EntityManager já fechou, pois ele esta configurado para viver no escopo de request (o que para o controle do banco é ótimo).

Neste momento o erro é org.hibernate.PersistentObjectException: detached entity passed to persist.

Se o bean não acusa erro o editar funciona, visto o EntityManager já estar aberto, pois ele foi usado para carregar o objeto que é apresentado na tela.

Mudar o escopo do EntityManager criaria o problema de ter que gerenciá-lo quando fechar e eu não quero isso.

Gostaria de saber o que posso fazer pra contornar esse problema e como voces resolvem isso.


Produtor do EntityManager

@Produces
@RequestScoped
public EntityManager createEntityManager() {
    return factory.createEntityManager();
}
public void closeEntityManager(@Disposes EntityManager manager) {
    manager.close();
}

Bean que cuida da tela de listar e do formulário.

@Named
@ViewScoped
public class PaisMB implements Serializable {

    private static final long serialVersionUID = 1L;

    @Inject
    private PaisFA paisFa;
    private LazyDataModel<Pais> lazyModel = null;
    private Pais paisSelecionado = null;

    public LazyDataModel<Pais> getLazyModel() {
        if (lazyModel == null) {
            lazyModel = paisFa.listaPais();
        }
        return lazyModel;
    }

    public Pais getPaisSelecionado() {
        if (paisSelecionado == null) {
            paisSelecionado = new Pais();
        }
        return paisSelecionado;
    }

    public void setPaisSelecionado(Pais paisSelecionado) {
        this.paisSelecionado = paisSelecionado;
    }

    public void deletePaisSelecionado() {
        try {
            paisFa.deletePais(getPaisSelecionado());
            JSFUtil.sendInfoMessageToUser("O país "" + getPaisSelecionado().getNome() + "" foi deletado com sucesso.");
        } catch (Exception ex) {
            (...)
        }
    }

    public String salvarPaisSelecionado() {
        try {
            paisFa.savePais(getPaisSelecionado());
            JSFUtil.sendInfoMessageToUser("O país "" + getPaisSelecionado().getNome() + "" foi salvo com sucesso.");
            return "/paisLista?faces-redirect=true";
        } catch (Exception ex) {
            (...)
        }
        return null;
    }

}

Item editar do na listagem de dados.

<p:menuitem value="Editar" icon="fa fa-edit" action="paisForm?faces-redirect=true&amp;includeViewParams=true">
    <f:setPropertyActionListener target="#{paisMB.paisSelecionado}" value="#{paisMB.paisSelecionado}" />
</p:menuitem>

Recebendo o parâmetro no formulário.

<f:metadata>
    <f:viewParam name="pais" value="#{paisMB.paisSelecionado}" converter="#{dbEntityCO}" />
</f:metadata>

Converter

@Named("dbEntityCO")
@ApplicationScoped
public class DBEntityCO implements Converter {

    @Inject
    private EntityManager entityManager;

    @Override
    public Object getAsObject(FacesContext context, UIComponent component, String value) {
        // aqui usa o EntityManager
        (...)
        return objeto;
    }

    @Override
    public String getAsString(FacesContext context, UIComponent component, Object value) {
        (...)
        return string;
    }
}

One Answer

Cara, aqui eu uso assim.

@ApplicationScoped
public class EntityManagerProducer {

    private EntityManagerFactory factory;

    public EntityManagerProducer() {
        factory = Persistence.createEntityManagerFactory("Thunder");
    }

    @Produces
    @RequestScoped
    public EntityManager createEntityManager(){
        return factory.createEntityManager();
    }

    public void closeEntityManager(@Disposes EntityManager manager){
        manager.close();
    }

}

Answered by Jonathan on October 14, 2020

Add your own answers!

Related Questions

Problema com JavaFx

2  Asked on December 7, 2021 by igor-freitas

       

Como usar store procedure com Doctrine

2  Asked on December 5, 2021 by fernando-silva

       

Performance ao comparar campos Varchar no SQL Server

1  Asked on December 5, 2021 by cmcampos86

   

SetTimeOut não funciona

2  Asked on December 5, 2021 by felipe-oliveira

 

Como usar o somatório em Julia?

1  Asked on December 5, 2021 by raquel-santos

 

como fazer um gráfico em vba excel em forma de metas?

1  Asked on December 4, 2021 by three-d-p

   

Combobox receber dados no segundo campo (list menu)

1  Asked on December 4, 2021 by csar-mattos

       

cURL error 6: Could not resolve host

0  Asked on December 4, 2021 by thiago-costa

       

Problemas ao renderizar componente react após array filter

1  Asked on December 4, 2021 by aniello-sansone-filho

 

Erro Repositório Git / Github

1  Asked on December 4, 2021 by paulo-csar-barbosa

   

Problema “o arquivo ja esta sendo usado por outro processo”

1  Asked on December 4, 2021 by lucas-fellipe-mondini-pereira

     

Calcular soma de dígitos de um número

11  Asked on December 2, 2021

 

Passar um texto para um EditText

1  Asked on December 2, 2021 by j-young

     

Como fazer busca dentro de uma RecycleView?

1  Asked on December 2, 2021 by franciscom

     

Como retirar NA de um dataframe no R?

2  Asked on December 2, 2021 by alexandre-sanches

   

Ask a Question

Get help from others!

© 2022 AnswerBun.com. All rights reserved. Sites we Love: PCI Database, MenuIva, UKBizDB, Menu Kuliner, Sharing RPP, SolveDir