1 2 Previous Next 17 Replies Latest reply on Jul 13, 2007 4:28 PM by wschwendt

    two basic questions for EntityHome

    azalea

      Hi,

      I'm writing a CRUD app using a extended EntityHome class.

      *** Q1 ***
      I want to reuse one EntityHome instance for more than one CRUD operations in a long-running conversation.
      But EntityHome instance is caching the entity and other states.
      How can I reset the state of EntityHome instance before each CRUD operations?

      setInstance(null);
      setInstance(createInstance());
      initInstance();
      clearDirty();
      ... ...
      

      I'm confusing...
      Does EntityHome provide such a reset method now?

      *** Q2 ***
      If calling persist(), update(), or remove() method of EntityHome is successful,
      EntityHome adds a JSF message automatically(ex. "successfully created").
      How can I clear this message?
      facesMessages.clear() didn't work.

      Thanks in advance.


        • 1. Re: two basic questions for EntityHome

          Hi azalea,

          Do you have the Seam source code with you? The answer is probably in front of you in Home.java, which is what EntityHome extends. It's a pretty simple class to understand, and it'll also answer your question 2.

          For your question2, you can override the *Messages() methods.

          • 2. Re: two basic questions for EntityHome
            azalea

            Hi, Seam framework master :)

            Thanks again.


            For your question2, you can override the *Messages() methods.

            I see!

            I do not yet understand the answer of the question 1.
            I will see seam source code now.

            Thanks.

            • 3. Re: two basic questions for EntityHome

              Hello,

              You asked how to reset the EntityHome so pay close attention to getInstance() in Home.java and see how you can nullify certain logic to get what you want. Beware, however since this is undocumented it can change from release to release and your application might break since you are depending on the implementation details. Having said that, the chances of that happening is probably remote.

              • 4. Re: two basic questions for EntityHome
                wschwendt

                 

                "azalea" wrote:
                I'm writing a CRUD app using a extended EntityHome class.

                I want to reuse one EntityHome instance for more than one CRUD operations in a long-running conversation.
                But EntityHome instance is caching the entity and other states.
                I'm confusing...
                Does EntityHome provide such a reset method now?



                thanks for asking this question! Incidentally, I spent the last 5 hours on this before looking into this forum and discovering that someone else is interested in this topic.

                My idea (that doesn't work yet):
                In my class that extends EntityHome/Customer\, where Customer is the type of my example Entity, I thought about adding the following method:

                 public String reset() {
                 log.debug("wos: kundeHome.reset() called");
                 setInstance(null);
                 setId(null);
                 return "reset";
                 }
                


                One thing to note is that not only the instance property needs to set to null, but also the id property. If only the instance property is null, but the id property remains at the old value, then when getInstance() is called, initInstance() of org.jboss.seam.framework.Home tries to load the old entity again.

                But my approach doesn't work yet. And for some reason I don't know, the instance property of my EntityHome component gets exported to Conversation scope. Why???

                For example, if my EntityHome component is named "customerHome", then in Conversation scope the context variable customerHome.instance gets set. I'd like to know why. I looked at the code of EntityHome/E\ and Home/EntityManager, E\, but I do not find where and why customerHome.instance gets set.

                Any hints would be highly appreciated.


                • 5. Re: two basic questions for EntityHome
                  wschwendt

                  For testing purposes I've defined an EntityHome component using components.xml

                  <framework:entity-home name="customerHome"
                   entity-class="Customer"
                   entity-manager="#{entityManager}"/>
                  



                  If a page accesses #{customerHome} via EL, then in the conversation context a context variable named customerHome gets set. Possibly because org.jboss.seam.framework.Home is annotated with @Scope(ScopeType.CONVERSATION)


                  If a page page accesses #{customerHome.instance} via EL, then in the conversation context not only the context variable named customerHome gets set (as expected), but in addition to it also a context variable named "customerHome.instance" (NOT expected).

                  This raises the question why "customerHome.instance" gets set. I've searched for any outjection code, but so far without success. Probably I have tomatoes on my eyes.

                  azalea, does a context variable named "EntityHomeName.instance" gets set in your case, too?

                  Perhaps this could be the reason for the caching behavior.


                  Where in the seam code happens the outjection to the "customerHome.instance" context variable?


                  • 6. Re: two basic questions for EntityHome
                    matt.drees

                    I think it happens in ManagedEntityIdentityInterceptor, though I don't really understand why it's done.

                    • 7. Re: two basic questions for EntityHome
                      wschwendt

                       

                      "matt.drees" wrote:
                      I think it happens in ManagedEntityIdentityInterceptor, though I don't really understand why it's done.


                      yes, it does, the interceptor writes to Conversation context. Thanks! There could possibly be a bug in ManagedEntityIdentityInterceptor.entityRefsToIds().

                      I don't really understand this code yet, but at least there is a suspiciously looking if condition:

                      public void entityRefsToIds(InvocationContext ctx) throws Exception
                      {
                      ...
                      
                       if (value!=null)
                       {...
                       }
                      


                      Raises at least the following question: What should happen if (value==null) and in conversation context there is a wrapper saved by a previous interceptor invocation? I think the context var for this previously saved wrapper possibly (*) needs to be deleted.


                      (*) possibly because it's just a wild guess from me whose understanding of the interceptor is still very limited



                      • 8. Re: two basic questions for EntityHome
                        azalea

                        Hi,


                        azalea, does a context variable named "EntityHomeName.instance" gets set in your case, too?

                        Yes, it does.


                        I think it happens in ManagedEntityIdentityInterceptor,

                        Thanks.
                        Hmmm...
                        It seems to be very difficult for me to understand that code,
                        but I will enjoy "open source" for a while :)


                        • 9. Re: two basic questions for EntityHome
                          azalea

                          Hi,

                          I initialized the EntityHome states in the following code.

                          public class PersonManager extends EntityHome<Person> {
                          
                           ... ...
                          
                           @Begin(join=true)
                           public void startCreate() {
                           debug("startCreate() called: id[#0]", getId());
                           setId(null);
                           initInstance();
                           }
                          
                           @Begin(join=true)
                           public void startUpdateOrDelete() {
                           debug("startUpdateOrDelete() called: id[#0]", getId());
                           initInstance();
                           }
                          
                           ... ...
                          
                          }
                          

                          If "create" <s:button> in "personList.xhtml" is clicked, startCreate() method is invoked and personEdit.xhtml is rendered.
                          If "edit" or "delete" <s:link> in personList.xhtml is clicked, the selected personId is bound to #{personManager.id}, startUpdateOrDelete() method is called, and personEdit.xhtml is rendered.

                          My simple crud app seems to work now.

                          wschwendt, how about your crud app?



                          • 10. Re: two basic questions for EntityHome
                            wschwendt

                             

                            "azalea" wrote:

                            wschwendt, how about your crud app?


                            azalea, I'm not writing any CRUD app in the sense that I'm developing something for a commercial client project. I'm not doing anything commercial right now. Roughly speaking, my interest is to find an approach how to systematically develop web apps with Seam.
                            Therefore, I'm trying to get an understanding of the semantics of Seam.

                            Now back to our problem:
                            I'd need to take a closer look at your solution and why it works, before I can comment on it. But I'm still very interested in the original question and the behavior of the ManagedEntityIdentityInterceptor.

                            EntityHome looks to me like a general seam component; the culprit for the caching behavior appears to be the ManagedEntityIdentityInterceptor.

                            And given that EntityHome is a general component, I'd expect to get this caching behavior probably for other stateful components as well.

                            Therefore, I'd be very interested in the answer whether the current behavior of ManagedEntityIdentityInterceptor is really as intended or whether it is a bug. At least it looks to me like a potential bug, but my understanding is still limited, so I'm not sure whether I should file it in JIRA.

                            Clearly, if there is a caching behavior caused by ManagedEntityIdentityInterceptor, its semantics should be defined.
                            And it is a basic fundamental feature that really influences seam apps.

                            Comments by Seam gurus would therefore be highly appreciated.

                            regards, Wolfgang





                            • 11. Re: two basic questions for EntityHome
                              gavin.king

                               

                              I don't really understand this code yet, but at least there is a suspiciously looking if condition:



                              Yes, looks like a bug, exactly on the line you saw. Would you please report this in JIRA, thanks.

                              • 12. Re: two basic questions for EntityHome
                                wschwendt

                                 

                                "gavin.king@jboss.com" wrote:
                                Yes, looks like a bug, exactly on the line you saw. Would you please report this in JIRA, thanks.


                                thanks for your comment.

                                Issue now filed at
                                http://jira.jboss.org/jira/browse/JBSEAM-1654

                                • 13. Re: two basic questions for EntityHome
                                  gavin.king

                                  Please test the fix.

                                  • 14. Re: two basic questions for EntityHome
                                    wschwendt

                                     

                                    "gavin.king@jboss.com" wrote:
                                    Please test the fix.


                                    Sorry for not replying earlier. The CVS checkout of the entire source tree was very slow yesterday. Atfer it was finally finished, I built a Seam version based on this source tree yesterday evening.

                                    Looking at your modification of ManagedEntityIdentityInterceptor, the added method clearWrapper() looks ok to me. But unfortunately, I cannot really test it, because i ran into other problems with the Seam version built with the CVS source.

                                    In short, when I define an EntityHome component using XML,
                                    a context var. with the name of this component is stored in conversation context and bound to an object of a class like org.jboss.seam.framework.EntityHome_$$_javassist_14

                                    This class has all the expected properties such as
                                    createdMessage Successfully created
                                    deletedMessage Successfully deleted
                                    entityClass class aws.objekte.Customer
                                    entityManager org.jboss.seam.persistence.EntityManagerProxy@186a830
                                    id
                                    idDefined false
                                    instance Customer custNum: 0 firstName: null lastName: null
                                    managed false
                                    newInstance



                                    In contrast, when I define an EnityHome component by extension and annotate it with @Stateful, the corresponding context var. in conversation context is bound to a class such as
                                    class org.javassist.tmp.java.lang.Object_$$_javassist_15

                                    As this class is defined by extension of EntityHome, it should have the properties shown above such as createdMessage, id, instance etc.


                                    But in my case it surprisingly has only the following 3 properties, with all the other properties missing:

                                    id
                                    managed
                                    toString()
                                    (all other properties such as "createdMessage" or "instance" missing).

                                    Consequently, when an EL expression is evaluated that references the instance property of this EntityHome component, an exception is thrown
                                    javax.el.PropertyNotFoundException, Property 'instance' not found on type

                                    Which is no surprise, given that the generated Java assist class shown above is lacking (not only) the instance property.


                                    1 2 Previous Next