Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to deal with 'cached' instance in @ViewScoped page?

App running with JSF, Primefaces, eclipselink, not a small app, about 100 pages/bean all working perfectly

I got some troubles understanding how my @ViewScoped page works, I got a select UI component, filled with a simple List<People> and a back-end selectedPeople in my bean


// all getters, setters, JPA annotations, all good
public class People {
    private String name;
    private List<Car> cars;
}

@ManagedBean
@ViewScoped
public class PeopleBean {
    @EJB
    private Service sPeople;
    private People selectedPeople;
    private List<People> listPpl;

    @PostConstruct
    public void init(){
        listPpl = sPeople.readAll();      // always good, same as DB values
    }

    public People getSelectedPeople(){
       return selectedPeople;
    }

    public People setSelectedPeople(People p){     // p is an old element
       selectedPeople = p;                         // BREAKPOINT
    }

    // getter for the list too
    public void method(){
        Logger.getAnoymousLogger().severe(selectedPeople.getCars()); // the one the old people, not the ne contained in the actual list
    }
}

<p:selectOneMenu id="selectP" value="#{peopleBean.selectedPeople}" converted="#{genericSecuerdConverter}" >
    <p:ajax event="change" partialSubmit="true" listener="#{peopleBean.method()}" />
    <f:selectItems value="#{peopleBean.listPpl}" var="people" itemLabel="#{people.name}" itemValue="#{people}" />
</p:selectOneMenu>

Sequence of use and problem is (information taken from debugging) :

  • go to peoplePage.xhtml where the select element is, IDs of the list's element are #410, #411, #412 (3 peoples)
  • go to modif.xhtml, change the 3rd people (remove a car, saved in DB (check in DB))
  • come back to peoplePage.xhtml, list is OK, IDs in debug are #650, #651, #652
  • change the value (from null) of the selectUI to choose a people, and at the breakpoint, p appears to be the #412 element, so the changes on its car's list are not visible, it does not come from the listPpl (because contains only valid elements and corresponds to DB), it's kind of caching

I tried to disable ecpliselink cache as states EclipleLink cache

  • change eclipselink property
  • change JPA propery
  • use @Cacheable(false)

No one had an effect, nor go to private navigation neither clear the browser cache and come back to the page, the p element is still the old one from first loading

I thought @ViewScoped allows to open a page each time as if it was the first time, but seems not, can't figure where the element can be stored/cached


Edit I used a workaround for the moment but this is obviously o the best solution

public People setSelectedPeople(People p){    
    if(p!=null)
        selectedPeople = sPeople.read(p.getId());                         
}
like image 621
azro Avatar asked Nov 07 '22 03:11

azro


1 Answers

What you are looking for is @RequestScoped. It will create everything each and every time you do a suitable HTTP request. Otherwise it is not guaranteed to destroy the @ViewScoped beans. An example in the Omnifaces documentation: ViewScoped.

This feature could be used to help the recreation of the page when the user is using the back and forward buttons of the browser for example.

@RequestScoped Bean lives as long as the HTTP request-response lives. It gets created upon a HTTP request and gets destroyed when the HTTP response associated with the HTTP request is finished.

@ViewScoped Bean lives as long as the user is interacting with the same JSF view in the browser window/tab. It gets created upon a HTTP request and gets destroyed once the user postbacks to a different view.

Source of descriptions: https://www.tutorialspoint.com/jsf/jsf_managed_beans.htm

like image 148
Hash Avatar answered Nov 14 '22 21:11

Hash