JPA / Primefaces - Add / Remove records from a child table

3

I have a problem with a cadastral panel.

There is a store network registry in which I am taking care of the implementation. I can normally insert and remove dataTable items, but this is not reflected in the base in the burning process - when I enter or remove an item from the branch list, the burning process simply ignores. I can not find what happens.

<p:dataTable rowIndexVar="idx" id="grdPj" var="pj"  
                            scrollable="true"
                            scrollHeight="275"
                            value="#{cadRedeMBean.rede.pessoaJuridicas}"
                            emptyMessage="" 
                            widgetVar="grid">                               
                            <p:column headerText="Cód." width="15%" >
                                <h:outputText value="#{pj.cdPessoaJuridica}"></h:outputText>
                            </p:column>
                            <p:column headerText="CNPJ" width="25%" >
                                <h:outputText value="#{pj.cdCnpj}"></h:outputText>
                            </p:column>
                            <p:column headerText="Nome Fantasia" width="50%" >
                                <h:outputText value="#{pj.nmFantasia}"></h:outputText>
                            </p:column>
                            <p:column headerText="Remover" width="10%" >
                                <p:commandButton icon="ui ui-icon-minusthick" title="Remover loja da rede" action="#{cadRedeMBean.delFilial}" update="grdPj">
                                    <f:setPropertyActionListener
                                        target="#{cadRedeMBean.filial}" value="#{pj}"></f:setPropertyActionListener>
                                </p:commandButton>
                            </p:column>                             
                        </p:dataTable>

Here is the xhtml, where you have the button that calls the delete method, which is this below, which accompanies the method to add.

    public void addFilial(){
    if (filial instanceof PessoaJuridica){
        rede.addPessoaJuridica(filial);
    }
}

public void delFilial(){
    if (filial instanceof PessoaJuridica){
        rede.removePessoaJuridica(filial);          
    }
}

The method to update the network follows a merge (or a persist, in case of insertion) in the network object.

Updating - Models

Network

@Entity
@Table(name="REDE")
@NamedQuery(name="Rede.findAll", query="SELECT r FROM Rede r")
public class Rede implements Serializable {
    /*Aqui tem Hashcodes e Equals*/
    private static final long serialVersionUID = 1L;
    private long cdRede;
    private String nmRede;
    private List<PessoaJuridica> pessoaJuridicas;
    private PessoaJuridica pessoaJuridica;

    public Rede() {
    }


    @Id
    @GeneratedValue( strategy = GenerationType.SEQUENCE, generator = "SQ_CD_REDE" )
    @SequenceGenerator(name = "SQ_CD_REDE", sequenceName = "SQ_CD_REDE", allocationSize = 1)    
    @Column(name="CD_REDE")
    public long getCdRede() {
        return this.cdRede;
    }

    public void setCdRede(long cdRede) {
        this.cdRede = cdRede;
    }


    @Column(name="NM_REDE")
    public String getNmRede() {
        return this.nmRede;
    }

    public void setNmRede(String nmRede) {
        this.nmRede = nmRede;
    }


    //bi-directional many-to-one association to PessoaJuridica
    @OneToMany(mappedBy="rede", cascade=CascadeType.PERSIST)
    public List<PessoaJuridica> getPessoaJuridicas() {
        return this.pessoaJuridicas;
    }

    public void setPessoaJuridicas(List<PessoaJuridica> pessoaJuridicas) {
        this.pessoaJuridicas = pessoaJuridicas;
    }

    public PessoaJuridica addPessoaJuridica(PessoaJuridica pessoaJuridica) {
        getPessoaJuridicas().add(pessoaJuridica);
        pessoaJuridica.setRede(this);

        return pessoaJuridica;
    }

    public PessoaJuridica removePessoaJuridica(PessoaJuridica pessoaJuridica) {
        getPessoaJuridicas().remove(pessoaJuridica);
        pessoaJuridica.setRede(null);

        return pessoaJuridica;
    }


    //bi-directional many-to-one association to PessoaJuridica
    @ManyToOne
    @JoinColumn(name="CD_PESSOA_JURIDICA")
    public PessoaJuridica getPessoaJuridica() {
        return this.pessoaJuridica;
    }

    public void setPessoaJuridica(PessoaJuridica pessoaJuridica) {
        this.pessoaJuridica = pessoaJuridica;
    }

}

PersonalJuridica

@Entity
@Table(name="PESSOA_JURIDICA")
@NamedQuery(name="PessoaJuridica.findAll", query="SELECT p FROM PessoaJuridica p")
public class PessoaJuridica implements Serializable,Cloneable {
    private static final long serialVersionUID = 1L;

    @Id
    @GeneratedValue( strategy = GenerationType.SEQUENCE, generator = "SQ_CD_PESSOA_JURIDICA" )
    @SequenceGenerator(name = "SQ_CD_PESSOA_JURIDICA", sequenceName = "SQ_CD_PESSOA_JURIDICA", allocationSize = 1)
    @Column(name="CD_PESSOA_JURIDICA")
    private long cdPessoaJuridica;

    /**Demais colunas**/


    //bi-directional many-to-one association to Rede
    @ManyToOne
    @JoinColumn(name="CD_REDE_LOJAS")
    private Rede rede;


    //bi-directional many-to-one association to Rede
    @OneToMany(mappedBy="pessoaJuridica", cascade = CascadeType.ALL)
    private List<Rede> redes;

    /**Getters & Setters**/
}

Updating The call to write to the MBean

public void gravarRede() {
        RedeImpl qryRede = new RedeImpl();
        if (rede.getPessoaJuridica() instanceof PessoaJuridica){
            if (rede.getPessoaJuridicas() instanceof List){
                if (rede.getPessoaJuridicas().size()==0){
                    rede.setPessoaJuridicas(null);
                }
            }
            if (rede.getPessoaJuridica().getCdPessoaJuridica()==0){
                rede.setPessoaJuridica(null);
            }
            boolean novo = (rede.getCdRede()==0);
            qryRede.novoRede(rede);
            Long idNovo = rede.getCdRede();
            if (novo){
                new Fncts().aviso("Código "+idNovo);
            }else{
                new Fncts().aviso("Atualização realizada!");                
            }
        }       
    }

And newRede

public void novoRede(Rede rede){ 
      try{
        em.getTransaction().begin();
        if (rede.getCdRede()>0){
            em.merge(rede);
        }else{
            em.persist(rede);
        }
        em.getTransaction().commit();
      }catch(Exception ex){
        em.getTransaction().rollback();
        System.out.println("---ERRO!----"+ex.getMessage());
      }     
    
asked by anonymous 30.11.2015 / 20:14

1 answer

1

Your problem is related to cascade actions, for example: to factory hibernate (sessionfactory)

@Cascade(value = { CascadeType.PERSIST, CascadeType.MERGE,
                   CascadeType.DELETE, CascadeType.SAVE_UPDATE})

If you are using JPA factory, there are versions that have a bug, does not work right (factory JPA (entitymanager-factory)) JPA mapping. if you do not have constraints (design requirements) use the above code.

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

Another thing your child object, it has to make sense according to its action performed in cascade, suffered by the parent, take care not to generate a cycle, parent saves child, child saves the parent and enter an infinite loop.

Thus - > Save PAI - > child has Cascade Save and because a will, according to its desired action, suffered by the root, will propagate to the branches until reaching leaves.

Detail to remove objects, by list, it is mandatory to implement the hashCode methods and equals because without this implemented correctly does not work, this is not hibernate is java.

    
27.09.2016 / 01:47