Menu

Primefaces CRUD generator maintains duplicates entities in memory

2016-01-03
2016-04-13
  • Philippe Donze

    Philippe Donze - 2016-01-03

    I use :

    Netbeans 8.0.2
    Jdk 1.7.0-45
    Java EE Web 7 API libary
    JSF 2.2
    Primefaces 5.0
    Primefaces CRUD generator 0.34.2
    Hibernate 4.3.1
    Glassfish 4.1

    I built a small database, and generate the java CRUD using the primefaces CRUD generator.

    The transactions are well working but :

    If I enter a list all on a large entity table, then click on Home button, and click again on the same entity table then Home and so on, I can see using visualvm that the memory for that entity table grows and grows (duplicated and duplicated and so on).

    I tried to add a getEntityManager.clear() at end of findAll(), but that do not solve the problem.

    Is it a problem from myself ? But to build my transaction I followed the https://sourceforge.net/p/nbpfcrudgen/wiki/GettingStarted/ . Is it a problem using the CRUD generator?

    This cause problems at client site. Please, drive me to solve.

    Thanks in advance

     
  • Kay Wrobel

    Kay Wrobel - 2016-01-04

    Hi Philippe.
    I believe the problem you encounter has to do with the JPA layer reading in all records at a time, keeping the records in your view scoped bean. This has been a long-standing issue with the CRUD generator ever since it was conceived and even before that since the original CRUD appplication generated by NetBeans, which btw. kept all its data in session scope!

    That said, PrimeFaces DataTables have had the ability to Lazy Load a limited amount of data as the widget pages through data, which requires custom loading of the next set of data by the data layer. This feature has been incorporated recently in version 0.35 of the CRUD generator, but you must specify to default to it as you generate the pages. It is also not entirely fool proof as navigating to child pages of large entities can still cause a large amount of data to be loaded.

    If I were you, I would give version 0.35 a try and make sure you check the new Lazy Loading option. Generate a test application first and see if this can be used in your scenario. I also would like to point out that Hibernate as well as OpenJPA have their issues with Lazy Loading One-To-Many relationships. I would personally recommend to stay with EclipseLink, which is the defaul for GlassFish.

    Let me know if there is anything I can do to help.

     
    • Anonymous

      Anonymous - 2016-01-04

      Hi Kay,

      I did the test with 0.35 . I could not update/replace version in Netbeans 8.0.2 due to some package incompatibilities, but succeed with Netbeans 8.1.

      I could see the differences of the Primefaces CRUD generator. You did a great job using the LazyEntityDataModel in the new version. The access on tables occurs page after page with good performances and the number of entity objects is limited compared to the previous version.

      This is nice.

      Anyway, this do not fully solve my problem, because the customer may display pages with a lot of table records, and if he click on next page, then next page, and so, the heap space may have problems : I think it could be very nice to detach the entities that are not displayed on the screen (may be as an option) so that the memory can be free with these non necessary instances. I'm not sure if it is possible, because I'm currently bad at eclipseLink knowledge.

      Do you think it could be possible ?

      Also, I do not think I can use the version 0.35 in my client environment ( indicated in my previous message ) . Is this possible ?

      Thanks in advance

       
  • Philippe Donze

    Philippe Donze - 2016-01-04

    Thanks Kay for your answer. I'll try 0.35, but I'm not sure I'll able to use it at client site : their application was built 2 years ago with different versions and a different server and I think it will be difficult to upgrade their site, they use :

    Java EE6 Web
    JSF 2.1
    Jboss 7.1.1.Final
    JDK 7
    Hibernate 3.2.5
    Primefaces 3.5.0
    An older version of Primefaces CRUD generator

    Anyway I'll check and will send back my test results.

    Thanks for your help

     
  • Anonymous

    Anonymous - 2016-01-04

    Hi Kay,

    I did the test with 0.35 . I could not update/replace version in Netbeans 8.0.2 due to some package incompatibilities, but succeed with Netbeans 8.1.

    I could see the differences of the Primefaces CRUD generator. You did a great job using the LazyEntityDataModel in the new version. The access on tables occurs page after page with good performances and the number of entity objects is limited compared to the previous version.

    This is nice.

    Anyway, this do not fully solve my problem, because the customer may display pages with a lot of table records, and if he click on next page, then next page, and so, the heap space may have problems : I think it could be very nice to detach the entities that are not displayed on the screen (may be as an option) so that the memory can be free with these non necessary instances. I'm not sure if it is possible, because I'm currently bad at eclipseLink knowledge.

    Do you think it could be possible ?

    Also, I do not think I can use the version 0.35 in my client environment ( indicated in my previous message ) . Is this possible ?

    Thanks in advance

     
  • Philippe Donze

    Philippe Donze - 2016-01-04

    Hi Kay,

    I did the test with 0.35 . I could not update/replace version in Netbeans 8.0.2 due to some package incompatibilities, but succeed with Netbeans 8.1.

    I could see the differences of the Primefaces CRUD generator. You did a great job using the LazyEntityDataModel in the new version. The access on tables occurs page after page with good performances and the number of entity objects is limited compared to the previous version.

    This is nice.

    Anyway, this do not fully solve my problem, because the customer may display pages with a lot of table records, and if he click on next page, then next page, and so, the heap space may have problems : I think it could be very nice to detach the entities that are not displayed on the screen (may be as an option) so that the memory can be free with these non necessary instances. I'm not sure if it is possible, because I'm currently bad at eclipseLink knowledge.

    Do you think it could be possible ?

    Also, I do not think I can use the version 0.35 in my client environment ( indicated in my previous message ) . Is this possible ?

    Thanks in advance

     
  • Kay Wrobel

    Kay Wrobel - 2016-01-04

    Well, you could study the code and see if you can add the necessary parts to the existing site. There are only a handful of new classes. The AbstractFacade class has a few additional methods to generically handle the queries. And the JSF page(s) in question would require some tweaking. If you don't have to do this for each and every page or entity, I'd suggest to try that. Or, maybe, you just generate the new classes, but use the existing JSF pages and then modify the one or two pages where load is extremely heavy due to data volume. I tried to keep comments in the JSF list.xhtml page so you can see what needs to be changed to enable/disable LazyLoading in DataTable.

    Hope I made sense there, but I do think it is possible.

     
  • Kay Wrobel

    Kay Wrobel - 2016-01-04

    Regarding the memory leak, I'd have to take a look exactly how the enties are passed along. Probably what happens, with every new "page" of data, a new list gets created, but the old object is just left by the wayside. I thought that garbage collection would take care of such unassigned objects. But maybe garbage collection doesn't happen all that frequently in Glassfish? Idk, just a thought. I'll try to replicate the issue in a test environment and report back. Meanwhile, if you find out something, like an easy solution like a one or two liner, please let me know and I will test it also. Thanks, Philippe.

     
  • Anonymous

    Anonymous - 2016-01-23

    Hi Kay,

    The problem comes from @ViewScoped
    I did change it to @RequestScoped and memory leak do not appear anymore
    But I also did other changes, I'll revert some and tell you what is really needed

    Thanks Kay

     
  • Philippe Donze

    Philippe Donze - 2016-01-23

    Hi Kay,

    The problem comes with @ViewScoped
    I did change it to @RequestScoped and memory leak do not appear anymore
    But I also did other changes, I'll revert some and tell you what is really needed

    Thanks Kay

     

    Last edit: Philippe Donze 2016-01-23
  • Philippe Donze

    Philippe Donze - 2016-02-03

    Hi Kay,

    To well understanding the problem, there are some comments on the web, here are 2 of them :

    http://stackoverflow.com/questions/13091843/linked-viewscoped-beans-lead-to-memory-leaks

    http://stackoverflow.com/questions/13082379/destroying-view-scoped-beans-when-session-ends/13085978#13085978

    The solution I used for my customer is relatively easy :

    1) I used a new @SessionScoped bean to handle the items and the selected in AbstractController.java. I maintained the get/set for them in AbstractController, but these get/set take and set their values from my session scoped bean.

    @ManagedBean(name = "userSession")
    @SessionScoped
    public class UserSessionBean<t> implements Serializable {
    ...
    private T selected;
    private List<t> items;</t></t>

    ... get/set

    public abstract class AbstractController<t> implements Serializable {</t>

    private static final long serialVersionUID = 1L;
    
    @Inject
    private AbstractFacade<T> ejbFacade;
    private Class<T> itemClass;
    // private T selected;                <= commented out
    // private Collection<T> items;  <= commented out
    ...
    @ManagedProperty(value="#{userSession}")
    private UserSessionBean userSession;
    ...
    public T getSelected() {
        return (T) userSession.getSelected();
    }
    
    public void setSelected(T selected) {
        userSession.setSelected(selected);
    }
    
    public List<T> getItems() {
        if (userSession.getItems() == null) {
            userSession.setItems(this.ejbFacade.findAll());
        }
        return userSession.getItems();
    }
    

    2) In all controllers that inherit from AbstractController, I did change the @ViewScoped annotation to @RequestScoped

    3) In the session scoped bean, I create a listener to reset the selected and the items when clicing on the menu, it takes a String parameter to redirect to the next form to display. It is required to redirect in the listener because it seems primefaces do not support both the outcome and the listener in the xhtml.

    public void resetItems(String nextForm) {
        this.selected = null;
        this.items = null;
        resetTickets = true;
        StringBuilder formName = new StringBuilder();
        try {
            if (!firstForm) {
                formName.append("../");
            }
            firstForm = false;
            formName.append(nextForm).append("/index.xhtml");
            FacesContext.getCurrentInstance().getExternalContext().redirect(formName.toString());
        } catch (IOException ex) {
            log.error("Redirect to " + formName.toString() + " exception", ex);
        }
    }
    

    4) In the appmenu.xhtml, I did change all the menuitems like this :

    <p:menuitem value="Activity" outcome="/activity/index">
    to :
    <p:menuitem value="Activite" actionlistener="#{userSession.resetItems('activite')}"></p:menuitem></p:menuitem>

    This was enough, and there is no more memory leak navigation from menu to activity then to menu then to activity, etc... As said before I used jvisualvm ( from jdk7/bin ) to see the number of instances of my entities while navigating. This tool is easy to use and you can filter on java package, you can execute the GC and obtain a memory snapshot or a heapdump on a java process.

    OK, my solution works well when the entities do not use another entity ( it may be the case when a create or modify action on an entity need a findAll on another entity to fill a select list ). I do not needed it.

    If somebody need it, I guess you may have an array of selected and a dobble array for items, and a mechanic to reset the last list when the selected was done.. just a though...

    Also there are probably different solutions, may be better than mine...

    Cheers Kay, thanks for your support

     
  • Anonymous

    Anonymous - 2016-03-22

    I try to install Version: 0.34.2, but i got ths:

    Some plugins require plugin Contexts and Dependency Injection Support to be installed.
    The plugin Contexts and Dependency Injection Support is requested in implementation version 201510222201. The following plugin is affected:       PrimeFaces CRUD Generator
    Some plugins require plugin Web Common to be installed.
    The plugin Web Common is requested in implementation version 201510222201. The following plugin is affected:       PrimeFaces CRUD Generator
    Some plugins require plugin JSF API to be installed.
    The plugin JSF API is requested in implementation version 201510222201. The following plugin is affected:       PrimeFaces CRUD Generator Some plugins not installed to avoid potential installation problems.

    how should I do,

     

Anonymous
Anonymous

Add attachments
Cancel





Want the latest updates on software, tech news, and AI?
Get latest updates about software, tech news, and AI from SourceForge directly in your inbox once a month.