Search code examples
springjsfrichfaces

JSF multiple calls to getter causing service timeout


I am using JSF and spring . I have a spring managed bean in session scope. I am getting a quite big list from a service call . I am calling the service and getting the list In the getter which is bind to the jsf view. when I run the app the getter is called multiple times.

so before the list is returned it is invoked again and it times out.

The list is dynamic I need to get fresh list on page load and every minute the list is refreshed using richfaces a4j poll . The list has to be retrived everytime from database.

If I change the bean to request scope and move the service call to the constructor the performance is worse.

can anyone suggest a better archetecture to do this ?


Solution

  • JSF managed bean getters should absolutely not call services. They should just return the managed bean property. This property should be already prepared by a (post)constructor or (action)listener method. Those methods will be invoked exactly one time. Getters will be invoked multiple times as JSF needs to access the value.

    You need to rewrite your code as such that the first-time job is done in the (post)constructor of the managed bean and that the <a4j:poll> invokes a listener method which refreshes the list and that the getter does absolutely nothing else than just returning the property.

    Here's a basic kickoff example using the standard Java EE 6 artifacts. I don't do Spring, but you should be able to supplant this with Spring artifacts.

    @ManagedBean
    @SessionScoped
    public class Bean {
    
        private List<Entity> entities;
    
        @EJB
        private EntityService service;
    
        @PostConstruct
        public void load() {
            entities = service.list();
        }
    
        public List<Entity> getEntities() {
            return entities;
        }
    
    }
    

    with

    <a4j:poll action="#{bean.load}" interval="60000" render="someTableId" />
    

    See also:


    Unrelated to the concrete problem: if you have a rather large DB table (>1000 rows) then copying the entire DB table into Java's memory is a pretty bad idea. Implement pagination/filtering.