Classes relacionadas com FK não inserem dados no banco

3 respostas
T

Tenho uma aplicação web JSF com EJB e JPA de cadastro de clientes.

No banco o endereço do cliente é uma tabela separada onde há outra tabela para cidade e outra para estado: (Algumas restricções NOT NULL foram retiradas pra ver se funcionava algo)

TABLE Cliente (
  id_cliente NUMBER(5) NOT NULL,
  nome VARCHAR2(100) NOT NULL,
  data_nasc DATE NOT NULL,
  email VARCHAR2(100),
  rg VARCHAR2(20) NOT NULL,
  cpf VARCHAR2(14) NOT NULL,
  sexo VARCHAR(20),
  usuario VARCHAR2(50),
  senha VARCHAR2(50),
  PRIMARY KEY (id_cliente) 
);
TABLE Estado(
  id_estado NUMBER(5) NOT NULL,
  descricao_estado VARCHAR2(255),
  
  PRIMARY KEY (id_estado)
);
TABLE Cidade(
  id_estado NUMBER(5),
  id_cidade NUMBER(5) ,
  nome_cidade VARCHAR2(50),
  descricao_cidade VARCHAR2(255),
  
  PRIMARY KEY (id_cidade),
  FOREIGN KEY (id_estado) REFERENCES Estado (id_estado)
  );
TABLE Endereco(
  id_end NUMBER(5) not null,  
  cep VARCHAR2(9) NOT NULL,
  nome_cliente NUMBER(5),
  id_cidade NUMBER(5),
  rua VARCHAR2(50),
  bairro VARCHAR2(50),
  nr_endereco NUMBER(6),
  
  PRIMARY KEY (id_end),
  FOREIGN KEY (id_cliente) REFERENCES Cliente (id_cliente), 
  FOREIGN KEY (id_cidade) REFERENCES Cidade (id_cidade) 
);

Tenho uma página que cadastra o estado numa boa no banco, mas quando vou cadastrar uma cidade, selecionando um estado ja cadastrado, não registra a cidade. Assim não consigo cadastrar o endereço do cliente pois necessito de uma cidade cadastrada.
Vou colocar os código de Estado e Cidade, se me ajudarem nesse o erro é igual de Cidade para Cliente.

Classe Estado:

@Entity
@Table(name = "Estado")
@SequenceGenerator(name="EST_SEQ", sequenceName="Estado_Seq", initialValue=1, allocationSize=1)
public class Estado implements Serializable{
    
    @Id
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator="EST_SEQ")
    @Basic(optional = false)
    @Column(name = "id_estado")
    private Long id_estado;
    @Column(name = "nome_estado")
    private String nome_estado;
    @Column(name = "descricao_estado")
    private String descricao_estado;

Getters e Setters

Estado DAO:

@Stateless
public class EstadoDAO {
    
    @PersistenceContext(unitName = "PAP_PU")
    private EntityManager em;

    public void adicionar(Estado estado) throws Exception {
        
        if (estado.getId_estado() == null) {
            em.persist(estado);
        } else {
            if (!em.contains(estado)) {
                if (em.find(Estado.class, estado.getId_estado()) == null) {
                    throw new Exception("Erro ao atualizar os dados do Cleinte!");
                }
            }
            em.merge(estado);
        }
    }

    public void editar(Estado estado) {
        em.merge(estado);
    }

    public void remover(Estado estado) {
        em.remove(em.merge(estado));
    }

    public Estado find(Object id) {
        return em.find(Estado.class, id);
    }

    public List<Estado> findAll() {
        javax.persistence.criteria.CriteriaQuery cq = em.getCriteriaBuilder().createQuery();
        cq.select(cq.from(Estado.class));
        return em.createQuery(cq).getResultList();
    }

    public List<Estado> findRange(int[] range) {
        javax.persistence.criteria.CriteriaQuery cq = em.getCriteriaBuilder().createQuery();
        cq.select(cq.from(Estado.class));
        javax.persistence.Query q = em.createQuery(cq);
        q.setMaxResults(range[1] - range[0]);
        q.setFirstResult(range[0]);
        return q.getResultList();
    }

    public int count() {
        javax.persistence.criteria.CriteriaQuery cq = em.getCriteriaBuilder().createQuery();
        javax.persistence.criteria.Root<Estado> rt = cq.from(Estado.class);
        cq.select(em.getCriteriaBuilder().count(rt));
        javax.persistence.Query q = em.createQuery(cq);
        return ((Long) q.getSingleResult()).intValue();
    }
    
}

Classe Lógica de Negocio Estado:

@Stateless
@LocalBean
public class EstadoLN {
    
    @EJB
    private EstadoDAO dao;

    public List<Estado> getTodosEstados() {
        return dao.findAll();
    }
    
    public void adicionarEstado(Estado estado) throws Exception{
        dao.adicionar(estado);
    }
    
    public void removerEstado(Estado estado){
        dao.remover(estado);
    }
    
}

Managed Bean Estado:

@ManagedBean
@SessionScoped
public class EstadoBean {
    
    @EJB
    private EstadoLN estadoLN;
    
    private List<Estado> estados;
    private Estado estado;
    
    @PostConstruct
    public void init() {
        this.estado = new Estado();
        }
   
    public EstadoBean() {
    }


    public List<Estado> getEstados() {
        estados = estadoLN.getTodosEstados();
        return estados;
    }
    
    
    public String adicionarEstado() throws Exception {
        
        estadoLN.adicionarEstado(estado);
        estado = new Estado();
        return "clientes";
    }
    
        public Estado getEstado() {
        return estado;
    }

    public void setEstado(Estado estado) {
        this.estado = estado;
    }
  
    
    public String editarEstado(){
        
        return "listarClientes";
    }
     
    public String removerEstado(){
        estadoLN.removerEstado(estado);
        estado = new Estado();
        return "listarClientes";
    }
    
}

Pagina JSF com form de cadastro de estado:

<h:form id="formEstado" class="form-inline">  
                 
            
            <p:panelGrid columns="2" styleClass="semBorda">

            <p:outputLabel value="Estado:" for="estado"/>
                <p:inputText id="estado" value="#{estadoBean.estado.nome_estado}"/>

            <p:outputLabel value="Descrição:" for="descricao_estado"/>
                <p:inputText id="descricao_estado" value="#{estadoBean.estado.descricao_estado}"/>
                   
                <p:commandButton id="cadastrar" value="Cadastrar" action="#{estadoBean.adicionarEstado()}" icon="ui-icon-disk"/>
            </p:panelGrid>
            
</h:form>

Agora os códigos de Cidade...

Classe Cidade:

@Entity
@Table(name = "Cidade")
@SequenceGenerator(name="CID_SEQ", sequenceName="Cidade_Seq", initialValue=1, allocationSize=1)
public class Cidade implements Serializable{
    
    @Id
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator="CID_SEQ")
    @Basic(optional = false)
    @Column(name = "id_cidade")
    private Long id_cidade;
    @JoinColumn(name = "id_estado", referencedColumnName = "id_estado")
    @ManyToOne(optional = false)
    private Estado estadoId;
    @Column(name = "nome_cidade")
    private String nome_cidade;
    @Column(name = "descricao_cidade")
    private String descricao_cidade;
    
    public Cidade(){
      
    }

    public Cidade(Long id_cidade) {
        this.id_cidade = id_cidade;
    }

Getters e Setters

Cidade DAO:

@Stateless
public class CidadeDAO {
    
    @PersistenceContext(unitName = "PAP_PU")
    private EntityManager em;

    public void adicionar(Cidade cidade) throws Exception {
        
        if (cidade.getId_cidade() == null) {
            em.persist(cidade);
        } else {
            if (!em.contains(cidade)) {
                if (em.find(Cidade.class, cidade.getId_cidade()) == null) {
                    throw new Exception("Erro ao atualizar os dados do Cleinte!");
                }
            }
            em.merge(cidade);
        }
    }

    public void editar(Cidade cidade) {
        em.merge(cidade);
    }

    public void remover(Cidade cidade) {
        em.remove(em.merge(cidade));
    }

    public Cidade find(Object id) {
        return em.find(Cidade.class, id);
    }

    public List<Cidade> findAll() {
        javax.persistence.criteria.CriteriaQuery cq = em.getCriteriaBuilder().createQuery();
        cq.select(cq.from(Cidade.class));
        return em.createQuery(cq).getResultList();
    }

    public List<Cidade> findRange(int[] range) {
        javax.persistence.criteria.CriteriaQuery cq = em.getCriteriaBuilder().createQuery();
        cq.select(cq.from(Cidade.class));
        javax.persistence.Query q = em.createQuery(cq);
        q.setMaxResults(range[1] - range[0]);
        q.setFirstResult(range[0]);
        return q.getResultList();
    }

    public int count() {
        javax.persistence.criteria.CriteriaQuery cq = em.getCriteriaBuilder().createQuery();
        javax.persistence.criteria.Root<Cidade> rt = cq.from(Cidade.class);
        cq.select(em.getCriteriaBuilder().count(rt));
        javax.persistence.Query q = em.createQuery(cq);
        return ((Long) q.getSingleResult()).intValue();
    }  
    
}

Classe Lógica de Negócio Cidade:

@Stateless
@LocalBean
public class CidadeLN {
    
    @EJB
    private CidadeDAO dao;

    public List<Cidade> getTodasCidades() {
        return dao.findAll();
    }
    
    public void adicionarCidade(Cidade cidade) throws Exception{
        dao.adicionar(cidade);
    }
    
    public void removerCidade(Cidade cidade){
        dao.remover(cidade);
    }
    
}

Managed Bean Cidade:

@ManagedBean
@SessionScoped
public class CidadeBean {
    
    @EJB
    private CidadeLN cidadeLN;
    @EJB
    private EstadoLN estadoLN;
    
    private List<Cidade> cidades;
    private Cidade cidade;
    private List<Estado> estados;
    private Estado estado;
    
    @PostConstruct
    public void init() {
        this.cidade = new Cidade();
        this.estado = new Estado();
        }
   
    public CidadeBean() {
    }

    public List<Cidade> getCidades() {
        cidades = cidadeLN.getTodasCidades();
        return cidades;
    }
    
    public List<Estado> getEstados() {
        estados = estadoLN.getTodosEstados();
        return estados;
    }
    
    public String adicionarCidade() throws Exception {
        cidade.setEstadoId(estado);
        cidadeLN.adicionarCidade(cidade);
        return "clientes";
    }
    
        public Cidade getCidade() {
        return cidade;
    }

    public void setCidade(Cidade cidade) {
        this.cidade = cidade;
    }
  
    public Estado getEstado() {
        return estado;
    }

    public void setEstado(Estado estado) {
        this.estado = estado;
    }
    
    public String getNomeEstado() {
        return estado.getNome_estado();
    }
    
    public String editarCidade(){
        
        return "listarClientes";
    }
     
    public String removerCidade(){
        cidadeLN.removerCidade(cidade);
        cidade = new Cidade();
        return "listarClientes";
    }
    
}

Tela JSF com form de cadastro de cidade (utilizei um SelectOneMenu pra selecionar o Estado cadastrado, não sei se está certo assim):

<h:form id="formCidade" class="form-inline">  
                 
             <p:panelGrid columns="2" styleClass="semBorda">

            <p:outputLabel value="Cidade:" for="cidade"/>
                <p:inputText id="cidade" value="#{cidadeBean.cidade.nome_cidade}"/>
                
            <p:outputLabel value="Estado:" for="estado"/>
            <h:selectOneMenu class="form-control" value="#{cidadeBean.estado}" id="estado" required="true">
                                    <f:selectItem itemLabel="Selecione o Estado..." itemValue=""/>
                                    <f:selectItems value="#{cidadeBean.estados}" 
                                                   var="umNome"
                                                   itemLabel="#{umNome.nome_estado}" 
                                                   itemValue="#{umNome}">
                                    </f:selectItems>
                                </h:selectOneMenu>    

            <p:outputLabel value="Descrição:" for="descricao_cidade"/>
                <p:inputText id="descricao_cidade" value="#{cidadeBean.cidade.descricao_cidade}"/>
                   
                <p:commandButton id="cadastrar" value="Cadastrar" action="#{cidadeBean.adicionarCidade()}" icon="ui-icon-disk"/>
            </p:panelGrid>
            
            </h:form>

Desculpem os códigos extensos, mas espero que alguém me ajude, estou precisando muito, obrigado!!

3 Respostas

ErickRAR

Você tem que definir os Cascades para isso:
http://uaihebert.com/jpa-mini-livro-primeiros-passos-e-conceitos-detalhados/23/

T

Adicionei a cascade na classe Estado que estava faltando mas mesmo assim quando vou cadastrar uma cidade nova selecionando um estado ja cadastrado não vai.

Adicionei

@OneToMany(cascade = CascadeType.ALL, mappedBy = "estadoId")

Que faz referencia com a classe Cidade:

@JoinColumn(name = "id_estado", referencedColumnName = "id_estado") @ManyToOne private Estado estadoId;

T

Ninguém mais pra ajudar?

Criado 17 de novembro de 2014
Ultima resposta 29 de nov. de 2014
Respostas 3
Participantes 2