7 Replies Latest reply on Apr 22, 2005 1:42 PM by bill.burke

    LongLived mechanism

    rlhatcher

      Hello,

      I am considering using a stateful session bean with a long lived entityManager to manage an entity through a multi-step process (wizard-like). In the example kindly provided in the docs, the update is handled in the session bean with flushMode set to never.

      I would prefer to send the entity back to the client, and manage the updates in one step and in the past would have used a DTO to do just that - however I'm not clear how updates to the entity outside the stateless bean are managed.

      As far as I can see, there are the following choices:
      1. Use a DTO to communicate with the client, and have a single update in the session bean that calls the setters on the entity.
      2. Mirror the setter methods of the entity in the session bean (seems a bad idea)
      3. Send the entity back to the client and effectivly treat it as a DTO++

      Anyone have a view on how this should be done, or am I totally missing something simple??

      Thanks

      @Stateful
      public class ClientStateBean implements ClientState {
      
       @Inject @LongLived EntityManager theManager;
      
       private Client theClient;
      
       public Client findClient(Long theID) {
       theClient = theManager.find(Client.class, theID);
       return theClient;
       }
      
       public Client getClient() {
       return theClient;
       }
      
       @FlushMode(FlushModeType.NEVER)
       public void updateClient(Client theClient) {
       // seems wrong
       this.theClient = theClient;
       }
      
       @Remove
       public void saveClient() {
       // commits all changes.
       }
      
      }


        • 1. Re: LongLived mechanism
          kkoster

          From what I understand and have done with the implementation, when the detached Client object is returned to the context of the bean, you will need to merge it back into the EntityManager's context. In your case

          @FlushMode(FlushModeType.NEVER)
           public void updateClient(Client theClient) {
           this.theClient = theClient;
           this.theManager.merge(this.theClient)
           }
          


          Or, alternatively if you don't want the state of theClient to be persisted only after calling saveClient, defer the merge until then. The FlushMode annotation can be removed.

          • 2. Re: LongLived mechanism
            rlhatcher

            That does make sense to me, however I don't see the benefit of having a LongLived manager since the process of using the entity and merging it back in doesn't really take advantage of the long livedness (if that's a word). Or is it simply a convienent place to store the entity in between steps? I'm beginning to feel as though I'm using a feature simply because it exists, not that it solves a particular problem I have.

            • 3. Re: LongLived mechanism
              bill.burke

              kkoster is correct. You must merge().

              BTW, there is no reason to create a DTO. Entities can become DTOs. The Value object pattern is dead.

              • 4. Re: LongLived mechanism
                bill.burke

                It is less useful since you are merging...But it is still useful because no SQL UPDATE, INSESRT, or DELETE will happen until you flush() (or the container does it for you). So, merge()ing will not update the database if the flush mode is NEVER. (neither will persist() or remove()). Am I making sense?

                • 5. Re: LongLived mechanism
                  rlhatcher

                  That makes perfect sense. It matches conceptually whith what I had in mind, but I was overcomplicating the implementation slightly. Thanks for the help, you've saved me a lot of time.

                  • 6. Re: LongLived mechanism
                    ffray

                    Hi guys!

                    Did I miss something? No TOs? How do you transfer
                    the data to the client? By sending the whole Entity?
                    Isn't it a bit uncool to serialize a whole entity if it is
                    a top level one correlating with dozends of other entities
                    and those to the whole rest of the underlying db-structure?
                    Even if most things aren't loaded it might be a nice
                    packet to send, isn't it!?
                    How do you restrict the data to the needed portions?


                    "bill.burke@jboss.com" wrote:
                    kkoster is correct. You must merge().

                    BTW, there is no reason to create a DTO. Entities can become DTOs. The Value object pattern is dead.


                    • 7. Re: LongLived mechanism
                      bill.burke

                      @OneToMany(fetch=FetchType.LAZY)