9 Replies Latest reply on Mar 27, 2007 6:35 PM by Tony Herstell

    Conceptual/Best Practice Question

    Mark Jones Newbie

      I have home page view that displays a list of orders as a @DataModel. The user can customise the view via a drop list to display different versions of this data model. This therefore requires state to maintain the selection choice.

      Users are also potentially altering the results viewable in the DataModel all over the place in the application. Obviously I need to refresh the view under these circumstances.

      My thoughts so far -:

      1) Observable type data pattern but cant see how I can integrate this nicely. Are there 'hooks' anywhere i can use inside seam/hibernate? Ok i realise this is a bit off topic.

      2) Re-populate the data set on every view. How do I do this considering that I am using a DataModel? Currently I initalise the DataModel using a factory method.

      3) Something I have not thought of...

      Thanks in advance.

        • 1. Re: Conceptual/Best Practice Question
          Bradley Smith Master

          In your code that alters data raise an event:

           Events.instance().raiseEvent("YOUR_EVENT_NAME");
          


          In code that can refresh the data model:

           @Observer("YOUR_EVENT_NAME")
           public void refreshTheDataModel() {
          
           // your code to refresh the data model goes here
           }
          


          • 2. Re: Conceptual/Best Practice Question
            Mark Jones Newbie

            I love elegant solutions.

            Thanks a lot

            • 3. Re: Conceptual/Best Practice Question
              Mark Jones Newbie

              I am getting greedy now. Is there somewhere I can place the event call inside a @Conversational bean so that it will get fired on any @End call? I have many many ways to end a conversation here.

              I thought like this...

              @Remove @Destroy @RaiseEvent("YOUR_EVENT_NAME")
              public void destroy() {}
              
              ... although I suspect someone will call me naughty for doing this? This also requires me to ask if @Destroy is called directly after @End.
              


              • 4. Re: Conceptual/Best Practice Question
                Gavin King Master

                The booking example uses a transactionSuccessEvent for this.

                • 5. Re: Conceptual/Best Practice Question
                  Gavin King Master

                   

                  In your code that alters data raise an event:


                  It's better to use an afterTransactionSuccess event, more elegant txn model.

                  I am getting greedy now. Is there somewhere I can place the event call inside a @Conversational bean so that it will get fired on any @End call?


                  Seam has a built-in event that it fires at the end of every conversation. You can listen for that, and then raise an afterTransactionSuccess event from the listener.

                  • 6. Re: Conceptual/Best Practice Question
                    Mark Jones Newbie

                    Thanks for the response Gavin.

                    As the refresh is a potentially expenisve operation I wanted to limit it to just the conversation that bean is involved in. I noticed the org.jboss.seam.endConversation in the docs before but assumed it was any conversation as it lacks the '' part such as for pageflows org.jboss.seam.endPageflow..

                    Am I misreading (unlikely as whoever write the docs does a great job ;0)) or is there a way to limit the event interception to a single bean, or perhaps examine the event trigger on processing?

                    • 7. Re: Conceptual/Best Practice Question
                      Mark Jones Newbie

                      That should have read...

                      conversation as it lacks the '<name>' part such as for pageflows org.jboss.seam.endPageflow.<name>


                      • 8. Re: Conceptual/Best Practice Question
                        Gavin King Master

                        Well, can't you use an action in the jBPM process definition for that?

                        • 9. Re: Conceptual/Best Practice Question
                          Tony Herstell Master

                          I also have a stateful page view that displays a list of xxxx as a @DataModel.

                          I also have conversations external to the page that manipulate entries int he model.

                          I call back from the conversations... and manipulate the mode.

                          In my code that requires to manipulate the model Inject it.

                           /**
                           * Biject the Find Users Controller which has to refine its list of Users
                           * When we update the Users then we have to laise with the FindUsersController to refine its list of users.
                           */
                           @In(create=true)
                           private FindUserController findUserController;
                          



                          then call back to it
                           @End
                           @TransactionAttribute(TransactionAttributeType.REQUIRED)
                           public String create() {
                           log.info("> create");
                           user.getDates().setCreationDate(new Date());
                           user.setPassword(encryptionController.encrypt(user.getPassword()));
                           em.persist(user);
                           em.flush();
                           facesMessages.addFromResourceBundle(FacesMessage.SEVERITY_INFO, "user_create_successful");
                          
                           /*
                           * We need to add this user to the list of users in the session scoped FindUserController
                           */
                           if (findUserController != null) {
                           findUserController.addUserToExistingList(user);
                           }
                          
                           log.info("< create");
                           return "success";
                           }
                          
                          



                          In my model, it doesn't have to re-read anything from the database.

                          I found this useful as I had problems managing to get my stateful model to "re-read" from the database as it only kept reading from the cache! and I didn't know how to invalidate the cache.

                          It did save any reads from the database.

                          However, I am sure Gavins way is better.