Persistência em uma aplicação usando CDI+EJB3.1+JPA+JSF+FACELETS+GLASSFISH - RESOLVIDO

Olá pessoam estou começando a utilizar CDI e EJB… estou com um projeto pequeno pra fazer… e escolhi essas tecnologias para aprender a utilizar as tecnologias… bom… vamos aos problemas :slight_smile:

Vou considerar no problema utilizando duas entidades simples do projeto, PAIS e ESTADO… pra ser mais facil de explicar o problema…

Relacionamento das entidades UM pais para MUITOS estados.

Resumo do problema:

Das duas entidades, O crud da entidade Pais funciona perfeitamente, o problema se encontra na hora de cadastrar um estado.
Na tela de estado tenho apenas um inputext para escrever o nome do estado e um selectonemenu para escolher o pais e um botão save para persistir esse estado.

Esse selectOneMenu usa um Converter… que ja debuguei e está funcionando tbm… pra ter certesa que não era ele o problema… implementei aquela solução do BaseEntity pra eliminar os converters nesse caso… mas continuou do mesmo jeito… voltei a usar o converter novamente por via das duvidas…

Quando rodo a aplicação eu só consigo persistir um estado com um determinado pais, não consigo persistir varios estados com o mesmo pais, só consigo persistir um estado por pais.

o problema está na configuração das classes acredito eu… estou usando alguma anotação errada… ou outra coisa que precisa configurar no projeto e não estou sabendo.

Quanto a erros no console ou tela… não aparece nada… simplesmente após o clique no botao salva… ali mesmo fica… e nada…

Entidade Pais

@Entity
@Table(name="PAIS")
public class Pais implements Serializable {

	
	private static final long serialVersionUID = 1L;

	@Id
	@GeneratedValue(strategy=GenerationType.SEQUENCE, generator="paisSequenceId")
	@SequenceGenerator(name="paisSequenceId",sequenceName="pais_sequence_id",allocationSize=1)
	@Column(name="ID")
	private Integer id;
	
	@Column(name="NOME")
	private String nome;
	
	@Column(name="SIGLA")
	private String sigla;
	
	@OneToMany(mappedBy="pais")
	private List<Estado> estados;
   
...getters, setters, equals e hashcode configurados

Entidade Estado


@Entity
@Table(name="ESTADO")
public class Estado implements Serializable {

	/**
	 * Serializacao padrao
	 */
	private static final long serialVersionUID = 1L;
	
	@Id
	@GeneratedValue(strategy=GenerationType.SEQUENCE, generator="estadoSequenceId")
	@SequenceGenerator(name="estadoSequenceId",sequenceName="estado_sequence_id",allocationSize=1)
	@Column(name="ID")
	private Integer id;
	
	@Column(name="NOME")
	private String nome;
	
	@ManyToOne
	@JoinColumn(name="PAIS")
	private Pais pais;
...getters, setters, equals e hashcode configurados

EJB - PaisSession

@Stateless
@TransactionManagement(TransactionManagementType.CONTAINER)
@TransactionAttribute(TransactionAttributeType.REQUIRED)
public class PaisSession extends BasicSessionBean {

    /**
     * Serializacao padrao
     */
    private static final long serialVersionUID = 1L;

     /**
     * Initializer
     */
    @PostConstruct
    public void inicializando() {

        
    }

    /**
     * Destruindo a classe
     */
    @PreDestroy
    public void destruindo() {

        
    }
    
    
    /**
     * Construtor padrao
     */
    public PaisSession() {
        
        
    }

    /**
     * Lista todos os paises
     *
     * @return
     */
    
    public List<Pais> listAll() {

        return getList(Pais.class, "select pais From Pais pais");

    }

    /**
     * Salva um pais
     *
     * @param pais
     */
    
    public void save(Pais obj) {

        try {

            getEm().persist(obj);

        } catch (Exception e) {

            System.out.println(e.getMessage());

        }

    }

    /**
     * Remove um pais
     *
     * @param pais
     */
    
    public void remove(Pais obj) {

        try {

            getEm().remove(getEm().merge(obj));

        } catch (Exception e) {

            System.out.println(e.getMessage());

        }

    }

    /**
     * Alterar um pais
     *
     * @param pais
     */
    
    public void update(Pais obj) {

        try {

            getEm().merge(obj);

        } catch (Exception e) {

            System.out.println(e.getMessage());
        }

    }

    /**
     * Recupera um pais
     *
     * @param id
     * @return
     */
    
    public Pais find(int id) {
        
        try {
            return getPojo(Pais.class, "select pais from Pais pais where pais.id = ?1" ,id);  
        } catch (Exception e) {
            System.out.println("Erro no find: " + e.getMessage());
            return null;
        }
        
    }
      


}

EJB - EstadoSession

@Stateless
@TransactionManagement(TransactionManagementType.CONTAINER)
@TransactionAttribute(TransactionAttributeType.REQUIRED)
public class EstadoSession extends BasicSessionBean {

    /**
     * Construtor padrao
     */
    public EstadoSession() {
    }

    /**
     * Salva um Estado
     *
     * @param estado
     */
    public void save(Estado obj) {

        try {

            getEm().persist(obj);

        } catch (Exception e) {

            System.out.println(e.getMessage());
        }

    }

    /**
     * Altera uma estado
     *
     * @param estado
     */
    public void update(Estado obj) {

        try {

            getEm().merge(obj);

        } catch (Exception e) {

            System.out.println(e.getMessage());
        }

    }

    /**
     * Remover uma estado
     *
     * @param estado
     */
    public void remove(Estado obj) {

        try {

            getEm().remove(getEm().merge(obj));

        } catch (Exception e) {

            System.out.println(e.getMessage());

        }

    }

    /**
     * Recupera um estado
     *
     * @param id
     * @return
     */
    public Estado find(int id) {

        return getPojo(Estado.class, id);

    }

    /**
     * Lista todas os estados
     *
     * @return
     */
    public List<Estado> listAll() {

        return getList(Estado.class, "select estado From Estado estado");
    }
}

CDI - EstadoFace


@Named
@SessionScoped
public class EstadoFace extends BaseCDIBean<Estado> implements GenericCrudFace<Estado> {

    /**
     * Serializacao padrao
     */
    private static final long serialVersionUID = 1L;
    @Inject
    private EstadoSession bean;
    @Inject
    private PaisSession paisBean;
    
    private List<SelectItem> items;
   
    private List<Pais> paisList;


    /**
     * Construtor padrao
     */
    public EstadoFace() {

        setSelectedBean(new Estado());
        items = new ArrayList<SelectItem>();
        
    }
    
    @PostConstruct
    public void inicializando() {

        paisList = new ArrayList<Pais>(paisBean.listAll());
        System.out.println("Executou o @PostConstruct. Metodo executado após a classe ser instanciada");
    }

    @Override
    public void save(ActionEvent event) {

        try {

            if (getSelectedBean().getNome() == null) {
                
                MessagesUtil.incluidoErro("Dados estão nulos !");
          
            } else {
                
                bean.save(getSelectedBean());
                MessagesUtil.incluido();
                newBean();
            }

        } catch (Exception e) {
            MessagesUtil.excluidoErro(e.getMessage());
        }


    }

    @Override
    public void update(ActionEvent event) {

        try {

            if (getSelectedBean().getId() == null) {
                MessagesUtil.incluidoErro("Dados estão nulos !");
            } else {
                bean.update(getSelectedBean());
                MessagesUtil.incluido();
                newBean();
            }

        } catch (Exception e) {
            MessagesUtil.excluidoErro(e.getMessage());
        }

    }

    @Override
    public void remove(ActionEvent event) {

        try {

            if (getSelectedBean().getId() == null) {
                MessagesUtil.incluidoErro("Dados estão nulos !");
            } else {
                

                bean.remove(getSelectedBean());
                
                MessagesUtil.incluido();
                newBean();
            }

        } catch (Exception e) {
            MessagesUtil.excluidoErro(e.getMessage());
        }

    }

    @Override
    public List<Estado> listAll() {


        return bean.listAll();

    }

    @Override
    public Estado find(ActionEvent event) {

        return bean.getPojo(Estado.class, getSelectedBean().getId());

    }

    @Override
    public void clearAll(ActionEvent event) {

        setSelectedBean(null);
        setSelectedBean(new Estado());

    }

    @Override
    public void newBean() {
        setSelectedBean(null);
        setSelectedBean(new Estado());
    }

    public PaisSession getPaisBean() {
        return paisBean;
    }

    public void setItems(List<SelectItem> items) {
        this.items = items;
    }

    public List<Pais> getPaisList() {
        return paisList;
    }

    public void setPaisList(List<Pais> paisList) {
        this.paisList = paisList;
    }
    

    public List<SelectItem> getItems() {

        for (Pais obj : paisBean.listAll()) {

            items.add(new SelectItem(obj, obj.getNome()));

        }

        return items;
    }
}

Pagina estado.xhtml

<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<ui:composition template="./../../template/sistema/templateSistema.xhtml"
                xmlns="http://www.w3.org/1999/xhtml"
                xmlns:ui="http://java.sun.com/jsf/facelets"
                xmlns:h="http://java.sun.com/jsf/html"
                xmlns:f="http://java.sun.com/jsf/core"
                xmlns:p="http://primefaces.org/ui"
                >


    <ui:define name="breadCrumb">
        Cadastro de Estados
    </ui:define>

    <ui:define name="content">

        <h:form id="formDados">

            <p:growl id="messages" showDetail="true" sticky="true"/>         

            <h:outputText value="Estado: "/>  
            <p:inputText value="#{estadoFace.selectedBean.nome}" />
       
            <h:outputText value="País"/>
            <p:selectOneMenu value="#{estadoFace.selectedBean.pais}" converter="paisConverter" >
                <f:selectItems value="#{estadoFace.paisList}" var="pais" itemLabel="#{pais.nome}" itemValue="#{pais}"/>
            </p:selectOneMenu>

            <p:commandButton id="btNovo" value="Novo" actionListener="#{estadoFace.save}" update="formDados"/>  

        </h:form> 

    </ui:define>

</ui:composition>

PaisConverter


@FacesConverter(value="paisConverter")
public class PaisConverter extends ManualCDILookup implements Converter{
  
    @Override
    public Object getAsObject(FacesContext fc, UIComponent uic, String string) {
        
        System.out.println("Entrou no getAsOBJECT");
        
        Pais paisObj = new Pais();
        
        PaisSession bean = getFacadeWithJNDI(PaisSession.class);
        try {
            Integer id = Integer.parseInt(string);
            
            paisObj = bean.getPojo(Pais.class, "select pais from Pais pais where pais.id = ?1", id);
            
            System.out.println("CONVERTER- AsOBJECT- Pais ID: " + paisObj.getId() + " Nome do Pais: " +paisObj.getNome());
            
        } catch (Exception e) {
            
            System.out.println("ERRO no CONVERTER getASOBJECT: "+ e.getMessage());
        }   
        
        return paisObj;
        
    }

    @Override
    public String getAsString(FacesContext fc, UIComponent uic, Object obj) {
        
        System.out.println("CONVERTER - getAsSTRING");
        Pais pais = new Pais();
        pais = ((Pais) obj);
        return pais.getId().toString();
        
    }
    
}

Existem varios trechos de código que podem ser enxugados… logico que tive que mudar algumas coisas para facilitar no debug…

Se alguem souber o que eu posso está fazendo de errado… por favor me mostrem… :slight_smile:

Consegui resolver, estava usando o equals e hashcode gerado apartir do netbeans… reimplementei… e o caso foi solucionado