7 Replies Latest reply on May 26, 2009 5:31 PM by Binesh Gummadi

    Call method on page load to refresh data from database

    David Spark Newbie

      Hi, I'm having 2 problems trying to implement something. My Seam app uses a database that can also be updated by another system. I therefore want to force some data to be reloaded from the database each time certain pages are loaded to make sure it's current.


      My problems are that firstly I cannot figure out how to call a method on page load. I don't think I can use the action tag in pages.xml as this is executed before the page is rendered and all the things I tried resulted in an error with this method.


      Secondly I'm not sure of the best way to force the database data to be reloaded. The user has to logon to the app so I don't want to unset everything (entityManager.clear()?) as wouldn't this result in the user having to login again?


      Thanks for any help!

        • 1. Re: Call method on page load to refresh data from database
          Binesh Gummadi Novice

          help us understand why can't you use action tag in pages.xml? This is exactly what you wanted right? Read database before you render(load) a page.

          • 2. Re: Call method on page load to refresh data from database
            Brandon Simpson Newbie

            There are a few ways to do what you are trying to do.


            An action will execute on each request so this will provide exactly the hook you need to do something like loading data. You can also fine-tune whether to execute this only on initial requests or only on post backs if needed. If you want to only reload certain entities and keep others, I think you could do an entityManager.refresh() on the entity you would reloaded. entityManager.clear() will detach all the entities but that's not the same as clearing out everything stored in the session...it all depends on how you have your entityManager set up (what scope, etc. it's stored in).


            Another method that might be better suited to what you are trying to do is create a @Factory and scope it to request scope. A factory method can be used to automatically create (or load) objects into a scope.


            Hope this helps.

            • 3. Re: Call method on page load to refresh data from database
              David Spark Newbie

              Hi, my basic issue is that I want changes to my database to be immediately shown when the user refreshes the page. The problem is that once the page had been shown any changes to the underlying data is not shown until the user logs out of my app and logs in again.



              To solve this I was trying to use entityManager.clear() called from an action on page load. The theory was that once the page was loaded the entityManager would be cleared and therefore when the page was reloaded it would have to be repopulated with fresh data from the database.


              In my testing I had the associated method called in 2 ways. One was an s:button on the page and the other was the action tag in pages.xml. The button worked as expected (i.e. click button and then reload page and new data is shown) but the action resulted in an error:


              18:10:55,300 ERROR [LazyInitializationException] could not initialize proxy - no Session
              org.hibernate.LazyInitializationException: could not initialize proxy - no Session
                   at org.hibernate.proxy.AbstractLazyInitializer.initialize(AbstractLazyInitializer.java:57)
                   at org.hibernate.proxy.AbstractLazyInitializer.getImplementation(AbstractLazyInitializer.java:111)
                   at org.hibernate.proxy.pojo.javassist.JavassistLazyInitializer.invoke(JavassistLazyInitializer.java:166)
                   at uk.co.splendid.sms.client.Client_$$_javassist_620.getBranch(Client_$$_javassist_620.java)
                   at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
                   ...


              My assumption is that this is because, from what I have read, actions in pages.xml are executed before the page is rendered so the entityManager is cleared before the page tries to render the data which results in the error.


              The button can't be used in practice but shows that it's in theory possible, I just can't figure out how to call that action after the page is rendered rather than before.


              Or if there's another solution to refreshing data from the database then that would be fine too :-)


              Thanks!

              • 4. Re: Call method on page load to refresh data from database
                Brandon Simpson Newbie

                It looks to me from what you posted that your page action fired off like it is supposed to but that your entityManager and/or entities are not in the state that you think they are in. So first thing I would recommend is putting in a debug statement at the beginning of your action to see if it fired off, then you can work on figuring out how to handle the entityManager.


                There are lots of ways to set up and handle entityManagers, and if it's not done right you'll get exceptions like what you posted above. For example, if the entityManager is stored in the wrong scope or closes between requests, then your entities will be detached when you access them on a subsequent request and you'll get that LazyInitializationException.


                The way I handled this was to let Seam manager the entityManager and just use @In to inject it in my beans and set it to manual flush mode also. Seam then stores the entityManager in conversation scope and also won't automatically close it...which means you can keep accessing it across several requests.


                It's pretty complex to learn all the ins and outs but hopefully this will at least give you some place to start.

                • 5. Re: Call method on page load to refresh data from database
                  Pramod Nair Novice

                  You can also fine-tune whether to execute this only on initial requests or only on post backs if needed.

                  Can you please explain this. I have the same requirement bu when my dataTbale is sorted or filtered this action execute event is getting executed. Please help.




                  Brandon Simpson wrote on May 20, 2009 19:08:


                  There are a few ways to do what you are trying to do.

                  An action will execute on each request so this will provide exactly the hook you need to do something like loading data. You can also fine-tune whether to execute this only on initial requests or only on post backs if needed. If you want to only reload certain entities and keep others, I think you could do an entityManager.refresh() on the entity you would reloaded. entityManager.clear() will detach all the entities but that's not the same as clearing out everything stored in the session...it all depends on how you have your entityManager set up (what scope, etc. it's stored in).

                  Another method that might be better suited to what you are trying to do is create a @Factory and scope it to request scope. A factory method can be used to automatically create (or load) objects into a scope.

                  Hope this helps.


                  Click HELP for text formatting instructions. Then edit this text and check the preview.

                  • 6. Re: Call method on page load to refresh data from database
                    Binesh Gummadi Novice

                    What is the scope of your persistence managers(components.xml)?
                    What scope is the data retrieved from the database stored(In action class)?
                    Do you have any extended conversation?


                    Show us your method in action class, components.xml, xhtml file, pages.xml or corresponding *.page.xml

                    • 7. Re: Call method on page load to refresh data from database
                      Binesh Gummadi Novice

                      I believe Brandon meant this.


                      <action execute="#{actionClass.method}" on-postback="false" />



                      This action is not executed on postback. Hope this helps.