Menu

How to show the elements of a collection in the view?

2015-08-18
2015-09-16
  • Henrique Castro

    Henrique Castro - 2015-08-18

    Hello,

    This is not quiet simple, I try to explain the best I can:

    I have 3 classes:

    • ObjetivoEstrategico = Only the name is required to create one object of this class.
    • ObjetivoDeSoftware = You need a name and at least one object of ObjetivoEstrategico add to the collection in the view.
    • ObjetivoDeMedicao = You need a name and at least one object of ObjetivoEstrategico add to the collection in the view.

    But the entity ObjetivoDeMedicao has also a collection of ObjetivoDeSoftware, so if I add an object of ObjetivoDeSoftware to the collection in the view, I can get all the objects of type ObjetivoEstrategico inside the ObjetivoDeSoftware right?

    Showing in code lines:

    @Entity
    class ObjetivoEstrategico{
    
        @Required
        private String name;
    }
    
    @Entity
    class ObjetivoDeSoftware{
    
        @Required
        private String name;
    
        @Size(min = 1 )
        private Collection<ObjetivoEstrategico> objetivoEstrategico;
    }
    
    @Entity
    class ObjetivoDeMedicao{    
        @Required
        private String name;
    
        @Size(min = 1 )
        private Collection<ObjetivoEstrategico> objetivoEstrategico;
    
        private Collection<ObjetivoDeSoftware> objetivoDeSoftware;
    }
    

    Well, when i tried to create an object of ObjetivoDeMedicao is at least necessary one object of ObjetivoEstrategico, but i add an ObjetivoDeSoftware i can everything from there, I did this, using the @PreCreate and @PreUpdate annotacion.

    @PreCreate
    @PreUpdate
    public void ajustaObjetivos() {
        if (objetivoDeSoftware != null){
            for (ObjetivoDeSoftware obj_software : objetivoDeSoftware) {
                for (ObjetivoEstrategico obj_estrategico: obj_software.getObjetivoEstrategico()) {
                objetivoEstrategico.add(obj_estrategico);
                }
            }
        }
    }
    

    It works very well, but when i do click to add an ObjetivoDeSoftware to the collection in the view of ObjetivoDeMedicao, the elements should be add to the another collection, objetivoEstrategico, are there, but are not shown in the view. I used to print the elements of the collection by name and i could see that is not empty, however in the view, does not show nothing, and the object ObjetivoDeMedicao is created how its to suppose to be.

    Any ideias?

    Thanks.

     

    Last edit: Henrique Castro 2015-08-18
  • Javier Paniza

    Javier Paniza - 2015-08-20

    Hi Henrique:

    Add a @SaveAction to your objetivoDeSoftware collection. Refine the original save action adding the next code:

    public void execute() throws Exception {
        super.execute(); // The original save code
        getView().getRoot().resfreshCollections(); // This is the trick
    }
    

    Usually OpenXava calculate which part of the UI have to be resefreshed. By default when you execute an action of a collection this collection is refreshed in the UI, but not the other collection in the view. However, you can force the refresh of all the collections with refreshCollections().


    Help others in this forum as I help you.

     
  • Henrique Castro

    Henrique Castro - 2015-08-20

    Javier, the problem is worst than I thought.

    The annotacions @PreCreate and @PreUpdate realy did not work as I wanted.

    I will explain very simple.

    The entity ObjetivoDeSoftware has a collection objetivoEstrategico, right?

    So when I will create an ObjetivoDeMedicao, and I add in the collection objetivoDeSoftware, that is one of the collections inside the class ObjetivoDeMedicao (as you can see above in the orther explanaction), I need that all objects of the type ObjetivoEstrategico, presents in the collection objetivoEstrategico of ObjetivoDeSoftware, will be add to objetivoEstrategico collection inside ObjetivoDeMedicao.

    How can I do that?

    Because using the annotations I constantly get null value of the collections and cant add nothing at all.
    Besides, objetivoEstrategico is a collection of ObjetivoDeMedicao with @Size(min=1), so has to be at least one element there, by adding in the objetivoDeSoftware collection, objetivoEstrategico will have the elements automatically, import them from the object ObjetivoDeSoftware that I add.

    Thanks

     
  • Javier Paniza

    Javier Paniza - 2015-08-24

    Hi Henrique,

    I think I understand. Use the callback methods on the collection element itself, for example, an @PreCreate in ObjetivoEstrategico could do the trick.


    Help others in this forum as I help you.

     
  • Henrique Castro

    Henrique Castro - 2015-08-26

    I am not sure how to do that, can you give me an example?
    Thanks.

     
  • Javier Paniza

    Javier Paniza - 2015-08-28

    Hi Henrique,

    In the sectin 5.2 of this lesson of the course you have some examples of callback method usage:
    http://openxava.wikispaces.com/basic-business-logic_en


    Help others in this forum as I help you.

     
  • Henrique Castro

    Henrique Castro - 2015-09-02

    Hello Javier,

    I tried to use the annotacion @PostCreate, but is the same as @PreCreate.
    Reading the documentacion I could not find what a I need, any examples at all.

    I dont know how to @PreCreate in ObjetivoEstrategico can do the trick, because when I use that, there is a error message saying "The annotation @PreCreate is disallowed for this location".

    I want something that: after creating the entity, I want to call an fuction to execute, because I will have something add to the ObjetivoDeSoftware collection, with that element I can import from it all the elements of ObjetivoEstrategico and add to the collection, just after creating the entity itself, but I dont know what annotacion can get the job done or if I am thinking right about this.

    Thanks.

     
  • Javier Paniza

    Javier Paniza - 2015-09-04

    Hi Henrique,

    The problem is that when the entity is really create the colleciton is empty, is it?

    In that case an option could be having a method createOtherCollection() in the entity, and then create your own save action (refining the standard one) to call explicititly to this method at the end.


    Help others in this forum as I help you.

     
  • Henrique Castro

    Henrique Castro - 2015-09-14

    So Javier, I did this:

    *Function responsible to create a collection, if the original objetivoEstrategico of the entity is null, and add all the elements presents inside the objetivoDeSoftware. This function is inside the entity ObjetivoDeMedicao.

    **IMPORTANT: ObjetivoDeSoftware (entity) has a collection of objetivoEstrategico, thats why we use 2 loops.

    public void ajustaObjetivos() {
    
            if (objetivoDeSoftware != null){
                if(objetivoEstrategico == null){
                    objetivoEstrategico = new ArrayList<ObjetivoEstrategico>();
                }
    
                for (ObjetivoDeSoftware obj_software : objetivoDeSoftware) {
                    for (ObjetivoEstrategico obj_estrategico : obj_software.getObjetivoEstrategico()) {
                        objetivoEstrategico.add(obj_estrategico);
                    }
                }
            }
    }
    

    And I create an newAction as follow:

    public class CreateObjetivoEstrategicoAction extends SaveAction {
    
        public void execute() throws Exception {
    
            super.execute();
    
            String id = getView().getValueString("id");
    
            ObjetivoDeMedicao o = XPersistence.getManager().find(ObjetivoDeMedicao.class, id);
    
            if(o.getObjetivoEstrategico() != null && o.getObjetivoEstrategico().size() < 1)
                o.ajustaObjetivos();            
         }
    }
    

    The action above is locate at ObjetivoDeSoftware collection inside the entity ObjetivoDeMedicao:

    public class ObjetivoDeMedicao extends Objetivo
    {
    
        @ManyToMany
        @NewAction("ObjetivoDeMedicao.createObjetivoEstrategico")
        @JoinTable(
            name = "ObjetivoDeMedicao_BaseadoEm_ObjetivoDeSoftware"
            , joinColumns = {
                @JoinColumn(name = "ObjetivoDeMedicao")
            }
            , inverseJoinColumns = {
                @JoinColumn(name = "ObjetivoDeSoftware")
            })
        @ListProperties("nome")
        private Collection<ObjetivoDeSoftware> objetivoDeSoftware;
    
        @ManyToMany
        @Size(min=1)
        @JoinTable(
            name = "ObjetivoDeMedicao_BaseadoEm_ObjetivoEstrategico"
            , joinColumns = {
                @JoinColumn(name = "ObjetivoDeMedicao")
            }
            , inverseJoinColumns = {
                @JoinColumn(name = "ObjetivoEstrategico")
            })
        @ListProperties("nome")
        private Collection<ObjetivoEstrategico> objetivoEstrategico;
    

    But when I tried to add some ObjetivoDeSoftware to the collection in the view, i get the error:

    "The property viewObject does not exist in org.somespc.actions.CreateObjetivoEstrategicoAction"
    

    What is missing?
    Is this the right way to go?
    I think we are far away from the real problem....because its realy simple, but could be some commucation issues hahaha....

    For one more time, I will try to do my best to explain:

    When I add an element to the "Collection<ObjetivoDeSoftware> objetivoDeSoftware", the another collection of the entity, "Collection<ObjetivoEstrategico> objetivoEstrategico", needs to be full filled, because an single element of ObjetivoDeSoftware is an entity tha has "Collection<ObjetivoEstrategico> objetivoEstrategico" inside. Thats it.

    To help, this is the class that represents the entity ObjetivoDeSoftware:

    public class ObjetivoDeSoftware extends Objetivo{
    
        @ManyToMany
        @Size(min=1)
        @JoinTable(
            name = "ObjetivoDeSoftware_BaseadoEm_ObjetivoEstrategico"
            , joinColumns = {
                @JoinColumn(name = "ObjetivoDeSoftware")
            }
            , inverseJoinColumns = {
                @JoinColumn(name = "ObjetivoEstrategico")
            })
        @ListProperties("nome")
        private Collection<ObjetivoEstrategico> objetivoEstrategico;
    
        public Collection<ObjetivoEstrategico> getObjetivoEstrategico()
        {
        return objetivoEstrategico;
        }
    
        public void setObjetivoEstrategico(
            Collection<ObjetivoEstrategico> objetivoEstrategico)
        {
        this.objetivoEstrategico = objetivoEstrategico;
        }
    }
    
     

    Last edit: Henrique Castro 2015-09-14
  • Javier Paniza

    Javier Paniza - 2015-09-16

    Hi Henrique,

    SaveAction is to save the main entity, to save a collection element you have to use SaveElementInCollectionAction. So write your action in this way:

    public class CreateObjetivoEstrategicoAction extends SaveElementInCollectionAction {
    

    Help others in this forum as I help you.

     

Log in to post a comment.