1 2 Previous Next 29 Replies Latest reply on Jan 20, 2006 2:36 PM by coryvirok

    Interesting Client/EJB3Container design question

    pego

      I found this post in the EJB/JBoss forum (probably the wrong one), but I think it could be a nice argument to be deepened.

      "Ciovo" wrote:

      I'm building an application using ejb3 and jboss 4, and I'm trying to understand what is the best way to handle the communication between a remote client in java (used by a GUI) and the jboss container. I thought about these two modelling solutions, and I'm trying to tell what are the pros and cons (in my opinion) :

      1) The java client receives entity beans through a session bean, it manages and manipulates the objects and then it returns the object to the session bean (which merges the detached object).
      PROS:
      - Easy to develop: the java client uses the entity bean methods
      - Objects are distributed
      CONS:
      - The business logic is in the client
      - If the Entity Bean class is changed, the new .class must be copied into the client too
      - Entity Bean's methods can be used by malicious code without control

      2) The java client uses methods that return the object's ID, not the entire object. The ID is provided by methods in session beans that implement the business logic, and the client has only to call these methods (and catch the exceptions)
      PROS:
      - The business logic is all in server side
      - More control, trasparency and security in functionality is provided by the session beans to the client
      CONS:
      - Apparently more laborious development
      - Not a distributed object approach (without object benefits and necessity
      to use API)


      Are these two scenarios correct?
      Are there any other way to organize communication between entity object and java client?
      Considering security, flexibility, caching systems, and future developments, what could be a good scenario?
      The scenario I'm modelling is aproximately represented by two hundred entity beans.

      Where can I find more information and possibly some nontrivial example?


      I think that a "distribuited object" way could be more convenient to reduce developing times, but that the other way is more flexible and guarantees more transparency.
      Anybody has other to suggest?

        • 1. Re: Interesting Client/EJB3Container design question
          heinrich

          hi,
          i do not exactly understand why in the first case the business logic is on client side.
          The entity methods are probably the getters and setters. In my opinion this is no business logic.

          The fact, that when entities are changed the client has also to be changes is ok. But thats not so significant.
          If there are big changes in the entity, this would affect the client also if there are value object for the communication client <->server.

          The second case is in my opinion redundant. If you recieve only the id from a session been with which the next step asks a another session been for the aproppriate data. Why? When this data could be returned instead of the id?!?
          This is confusing.

          I'm going to build specific methods in my session been which will return entity objects with predefined data. Just like the LightValue Objects from ejb2.1. So the client knows exactly if it calls methods xyz from session A that there is the data z missing in this attribute, and so on. FetchType Lazy is my friend =)

          • 2. Re: Interesting Client/EJB3Container design question
            martinganserer

            Hello,

            I agree with heinrich. The approach with the id is very strange.
            If you work on a remote client there are only two possible ways to work with ejb:

            1. Working with Value Objects
            Build different value objects for every use case. A value object consists of one or more entity objects and maybe additional data.
            2. Build appropriate session bean methods for different use cases.
            Personally I would prefer this approach, because building different value objects for every use case and mapping between value and entity object all the time is much work! One might think about a generic approach of building and transfering Value Objects but I think this is hard to implement!

            • 3. Re: Interesting Client/EJB3Container design question
              martinganserer

              Hello,

              yesterday I was thinking about another approach that I will might consider for my apps with remote clients. Heinrich wrote that he creates different accessor methods in session beans for different use cases.
              Wouldn't it be nice to use only one method?
              Example:
              Let's assume one has a complex customer order entity bean. The line items are marked to be fetched lazy. On the remote client it should be necessary to get the customer order object only without and with the collection of line items.
              Why don't we build the method like this

              CustomerOrder getCustOrderById(int id,int loadLevel)
              {
               CustomerOrder order = (CustomerOrder) em.find(...);
               if(loadLevel > 1)
               {
               order.getLineItems();
               }
               return order;
              }


              I would define a load level of type integer to cover even more complex entity beans with a bigger object tree.
              As the client developer (hopefully) knows the structure of the entity beans it is up to him to select what parts of the tree he wants to load.

              The advantages a clear:
              - You don't need awful value objects
              - You don't have to create different methods for every use case


              What do you think about this?



              • 4. Re: Interesting Client/EJB3Container design question
                heinrich

                Hi Martin,

                not a bad idea. I think i will try to use it.
                But when we do it like this to read out Beans we also need an appropriate method to store beans.
                I it is not sufficiant so store a transfered new entity just by using

                em.persiste(myNewCreatedEntity);
                

                with nested classes.
                EntityB b = myNewCreatedEntity.getB();
                em.persist(b);
                em.persist(myNewCreatedentity);
                


                This was the only way a was able to store the new entity created in a remote client.

                But, ist monday an there are still 5 days to work on this =)
                Nice week

                martin

                • 5. Re: Interesting Client/EJB3Container design question
                  martinganserer

                  Hello heinrich,

                  I must admit that I don't understand exactly what you want to tell me.
                  But from my point of view persisting and/or merging an entity bean is not the problem when working with a remote client. You just have to build a proper remote method that covers that issue.

                  Example:

                  CustomerOrder persistOrder(CustomerOrder custOrder)
                  {
                   // Do the persisting job and maybe something else
                  }
                  


                  It even is no problem to persist other objects that might come from the client that are related to the custOrder bean.

                  Could you please explain your thoughts about that issue a bit more in detail? If you think that it shouldn't be discussed here you can write me an email. You already have my address. I am really interested in what you think about my approach because it will be the base for my own EJB3 Framework.

                  Thank you

                  • 6. Re: Interesting Client/EJB3Container design question
                    heinrich

                    Sure =)

                    i thought about if there are these methodes containing the loadlevel to obtain entities, there must be methods containing the loadlevel to store entities because the methods normaly do not know which nested objects are available. Know you can think about my confusing last post :-)

                    I don't know if this is correct but it was the only way i got my entities stored in the database.
                    Thats all for today know. I found a bogus design error in my database scheme and i'm really really upset about this.

                    Nice Knock-Off

                    martin

                    • 7. Re: Interesting Client/EJB3Container design question
                      martinganserer

                      Hello Heinrich,

                      from my point of view you don't need a load level within insert or update methods at all. You define the strategy that nested objects will be handeled when persisting in the entity beans by using the cascade type!
                      In my existing app (for example) I have a CustomerOrder entity bean.
                      The insert method only calls persist and the CustomerOrder-Object and my CustOrderLine Objects will be persisted automatically.

                      Any comments about that?

                      • 8. Re: Interesting Client/EJB3Container design question
                        heinrich

                        Hmm, ok i have to check this.
                        But sounds good :-)

                        • 9. Re: Interesting Client/EJB3Container design question
                          phon

                          i'm developping a similar application (java GUI and EJB3 server) and i'm struggling with the same problem..

                          My Customer object has lot of nested objects (Address, SaleCondition, etc) and right now i just grabbed the whole object in one fetch when returning query results, which i can't keep doing as it's extremely inefficient.

                          I like your idea of specifying a loadLevel (or maybe a load ENUM), very much. But my questions is, suppose you have fetched 'half' of your Customer object and the client needs some more data (suppose you have fetched the Address lazily). How do you merge the new data with the existing object on the client; Or should i fetch the whole object again?

                          I also agree with martin that you don't need store levels as it is handled by the cascade option, i see no need for client to persist half entities..

                          Also are either of you using any good books about EJB3, and specifically with EJB3 with regular java clients?

                          greetings!

                          • 10. Re: Interesting Client/EJB3Container design question
                            martinganserer

                            Hello,

                            thank you for your positive response.

                            In my application by using the load level strategy I only see the solution to fetch the whole object again - even if you already have half of the data.
                            This is not very effective but it is easy to handle.

                            Books:
                            As far as I know there are no books about EJB3 available yet. I think it will take half a year to get the first ones.

                            • 11. Re: Interesting Client/EJB3Container design question
                              lzdobylak

                              HI all!!
                              My idea is to keep Entity Beans in client side and set fetch to LAZY.
                              Session Beans returns Entity Instances with empty references.
                              If I get empty reference I catch Lazy exception and call another session bean method that returns full reference and I replace empty reference with return value from remote server.
                              I WOULD LIKE DO IN THIS WAY but don't know if it is possible.
                              code example:

                              try{
                              customer.getListOfPhones()
                              }catch(lazyexception e){
                              customer.setListOfPhones(UserRemoteInterface.getListofPhonesByCustId(customer.getId))
                              }
                              

                              I don't even know if it's possible what do you think?

                              • 12. Re: Interesting Client/EJB3Container design question
                                heinrich

                                Hmm, ok,
                                i think this would work.
                                Although this is not very nice. Why to use exception handling when you know when there is no nested data available?
                                But just do as you think and give leave us a note how it works.

                                • 13. Re: Interesting Client/EJB3Container design question
                                  phon

                                  i agree with heinrich
                                  i think it's a way that could work but i think it's better to make your structure so that no exceptions are thrown (as heinrich said, you know when they will be thrown)..

                                  • 14. Re: Interesting Client/EJB3Container design question
                                    lzdobylak

                                    Hi again.
                                    I've tried to do what I've written above and....
                                    I can't catch Lazy exception. Even if i catch "Exception" on highest possible level, it is throwed probably because it is on server side and on client only redisplayed ???
                                    I don't know

                                    1 2 Previous Next