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

Asked

Viewed 935 times

3

I have a problem in a cadastral panel.

There is a register of store network in which I am taking care of the implementation. I can normally insert and remove items from the datatable, but this is not reflected in the recording process base - when I insert or remove an item from the branch list, the recording process simply ignores. I can’t 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 xhtml, where you have the button that calls the deletion method, which is this one 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 for updating the network accompanies a merge (or persist if inserted) in the network object.

Updating - the 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;
    }

}

Personal

@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 record in 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 the new

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());
      }     
  • 1

    It is not very clear what you mean by "the recording process simply ignores". By clicking the removal button the method is not called? The item is not removed from the database?

  • @Diegom Sorry, yesterday in a hurry I ended up not being able to detail accurately. By clicking the removal button, the method delfilial is called and responds normally - the item is deleted from <p:dataTable> however, when saving, it does not delete the subsidiary reference of the base.

  • although not very recommended, try to run entityManager.flush() after the merge. If it doesn’t work suspicious it might be a mapping problem. It would be nice to [Edit] the question to contain the entities code.

  • You debugged the code to check if in fact the line rede.removePessoaJuridica(filial); is being executed?

  • Something else, getPessoaJuridicas().remove(pessoaJuridica); this call is removing the object from the list! Where is the call for removing the object in the database ?

  • @Jorgefields, the merge does not replicate all updates performed on the parent object, including removals from the child records?

  • I’m not sure, @Thiagopaiva. But still, where is the merge taking place? At which point in the code?

  • @Jorgecampos, I updated it. I’m even checking if it’s not something related to Cascadetype in the Onetomany annotations on the model, but I haven’t had any success so far.

  • Okay, now what’s missing is, at what point do you call the gravarRede? Your original question is that the changes are not being saved in the database, the table updates (because you removed the object from the list) but is not saved in the database. Nowhere in the code you showed, is there a call to gravarRede , so if you need it to save to the bank at the time of delete, it should be something like this: if (filial instanceof PessoaJuridica){ rede.removePessoaJuridica(filial); rede.gravarRede(); }

  • The gravarRede is called when clicking the save button, which is in the form. The idea of the process is to be able to remove and add the subsidiaries and at the time of the network update to make the inclusions and exclusions of the subsidiaries. .

  • Then nothing will be persisted in the database until you click the save button. The remove that calls the delFilial will remove records only from the Datatable. If your problem is the save button, put the code snippet that calls it.

Show 6 more comments

1 answer

2


Your problem is related to Actions, for example: for Factory Hibernate (sessionfactory)

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

If you are using Factory JPA, you have versions that have a bug, it does not work right this (Factory JPA(entitymanager-Factory)) JPA mapping. if there are no restrictions (design requirements) use the code above.

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

Another thing your child object, has to make sense as its action executed on the Scade, suffered by the father, care not to generate a cycle, father saves son, son saves the father and enters an infinite loop.

Thus -> Save FATHER -> son has Cascade Save and by will, as its desired action, suffered by the root, will or will not propagate to the branches until it reaches the leaves.

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

Browser other questions tagged

You are not signed in. Login or sign up in order to post.