Details Object

Discussions

J2EE patterns: Details Object

  1. Details Object (49 messages)

        One of the most common operations in EJB is "getting" data from entity beans. Consider a "User" entity bean, which models all the information of a user of a website. A User has a first name, last name, street address, telephone number, etc. The problem is that When trying to get this data from the entity bean, each call to a "getter" (ie: getFirstName(), getLastName(),...) involves a network round trip, transactional overhead on the part of the app. server, serialization, etc. Too many queries of this sort will make your transactions longer and your system less scalable.

        The solution to this problem is to make a plain java class (a details object) that contains all the attributes of the User Entity Bean. That is, create a UserDetailsBean that contains a first name, last name, phone number, etc, as well as getters and setters.

    Example: A User Entity Bean and Details Bean
    The method implementations are left out for brevity

    public class UserBean implements EntityBean {

    protected String userName;
    protected String password;
    protected String firstName;
    protected String lastName;

            public String getUserName();
            public setUserName(String name);

            public String getPassword();
            public setPassword(String password);

            public String getFirstName();
            public setFirstName(String fName);

            public String getLastName();
            public setLastName(String lName);

                    ...
            //ejb specific methods and business methods
    }

    public class UserDetailsBean implements Serializable{

    protected String userName;
    protected String password;
    protected String firstName;
    protected String lastName;

            public String getUserName();
            public setUserName(String name);

            public String getPassword();
            public setPassword(String password);

            public String getFirstName();
            public setFirstName(String fName);

            public String getLastName();
            public setLastName(String lName);

                    ...

    }//UserDetailsBean

      Note that the UserDetailsBean contains all the same attributes and getters and setters as the Entity Bean.

      Now when the client wants to get at the User's data, instead of calling a large number of "getter" methods, one must only call "getUserDetails", which will create a UserDetailsBean with a copy of the internal state of the User Entity Bean, and pass that to the client.

        Using this strategy will decrease network roundtrips associated with "getting" attributes of an entity bean from n (limited by the number of attributes of the entity bean) down to just one (the call to get the details object). Details Objects can also be used across "tiers" (ie: you can use details objects in JSP's to list entity bean contents).

        Once you have written details objects for all your entity beans, I have found that making your entity beans inherit from your details objects will clean up your code considerable because you can now move your attributes and getters/setters out of your entity beans (into the details objects).

         Your entity beans will now contain only business methods and ejb specific methods:

    public class UserBean implements EntityBean {

            //ejb specific methods and business methods
    }

    public class UserDetailsBean implements Serializable{

    protected String userName;
    protected String password;
    protected String firstName;
    protected String lastName;

            public String getUserName();
            public setUserName(String name);

            public String getPassword();
            public setPassword(String password);

            public String getFirstName();
            public setFirstName(String fName);

            public String getLastName();
            public setLastName(String lName);

                    ...

    }//UserDetailsBean

    Threaded Messages (49)

  2. Details Object[ Go to top ]

    Another important issue while considering performance of entity beans while loading them from the database is "references".When an entity bean is loaded,the whole graph of entity beans or java classes is loaded which are referenced by the entity bean.This certainly leads to performance bottlenecks.One of the solutions that we implemented in our projects was to use TopLink's indirection,while generating object to relational mapping for our persistent objects.TopLinks indirection loads the references,only if needed or specified in the code as marked "to be loaded"
  3. Details Object[ Go to top ]

    For people not using TopLink or other advanced entity bean containers, you can avoid loading the whole object graph by lazy loading your references, which will be the subject of pattern I will post here soon. :)

    Floyd
  4. Details Object[ Go to top ]

    I liked the idea to get the details object by making only one call. If the data underneth changes the remote method call could still fetch the current values, but how do we handle such situations?

  5. Details Object[ Go to top ]

    In the getter set the Details objects values to the current beans feild values like

    public DetailsObject getDetObjects()throws RemoteException{
      DetailsObject myDetails = new DetailsObject();
      myDetails.name = this.name;
      myDetails.age = this.age;
      
      return myDetails;

    }

    this object will have the current values each time u call the getter as it is the containers responsibility to update the field values of the EJB.
  6. Details Object[ Go to top ]

    We are also using ejb with toplink, and our basecode api is strongly tied to toplink. We have been debating recently the approach to take with entitybeans and toplink -- did you use toplink to replace entitybeans, or did you use entitybeans to wrap toplink objects, or did you find another solution?

    Thanks, Dan
  7. Details Object[ Go to top ]

    We use TOPLink to persist our domain (business data) objects. These are just regular java objects that happen to be mapped to the RDB using TOPLink. These plain classes are then manipulated by session beans on behalf of client interactions, just as if they were entity beans. So in a sense, we are using TOPLink to replace entity beans. Using TOPLink also largely solves one of the issues that a subsequent poster raised -- that of knowing what has changed in a object graph as TOPLink keeps track of such things and will only persist the dirtied parts of a graph at commit time.

    Tim
  8. Details Object[ Go to top ]

    In Java how does Toplink does this?

    In Apple's EOF they use Faulting and in the good old days of Objective-C they did a point swizzle withever the object at the end of the relationship was touched. ie. the lazily loaded the data but maintained the same reference pointer to keep existing associations valid. This was done using Objective-C's forwarding mechanism. But how is this done in Java? Presumably there are "holder" objects that are always referenced and they either contain the data or the details necessary to obtain the data but I'm interested in exactly how they implement their lazily loaded. What kind of operation triggers a lazy load?
  9. Details Object[ Go to top ]

    Presumably there are "holder"


    Yes, TOPLink has a ValueHolder class that acts as a 'smart' reference. You use it in place of the real reference and TOPLink will not actually read the data at the end of the ValueHolder relationship until you dereference it. For example, lets say that the object of type Dog has a logical relationship to an object of type Tail. Using indirection in TOPLink (the term used for lazy-loading), the reference to Tail looks like:

        ValueHolder tailHolder;

    and the accessor for Tail looks like:

        public Tail getTail ( )
        {
            return (Tail)tailHolder.getValue( );
        }

    while the mutator looks like:

        public void setTail ( Tail tail )
        {
            tailHolder.setValue ( tail );
        }

    So, the loading is triggered when the value holder is 'dereferenced' via the getValue( )method.

    This makes the fact that there is some TOPLink magic providing lazy loading of Tails transparent to users of Dog. You also have to provide a couple of helper methods to set and get the holder -- these are used internally by TL. You must also specify in the TL O/R mapping tool that you are using indirection for this relationship.

    Hope this helps.

    Tim
  10. Details Object[ Go to top ]

    Hi,
    The article abt passing a object back and forth is a good idea we followed the same thing but implemented it as a container object for the sake of ease .One clarification though why would ur setters require a return type.

    thanx
    Chandrasekaran.V
  11. Details Object[ Go to top ]

    What do you mean by "implemented it as a container object"?

    >One clarification though why would ur setters require a
    > return type.
       
    That was my mistake, and has since been fixed. Thanks.

       Floyd
  12. To make it clearer[ Go to top ]

    I fully agree with this pattern. However, at the end of the message, you mention that the entity bean class should inherit the Details object class. Why don't you make it clear in the example:

    public class UserBean extends UserDetailsBean implements EntityBean {

      //ejb specific methods and business methods
      
    }

    Also, it's worth mentioning that the getUserDetails() method will be far easier to implement in this case :

    public class UserDetailsBean implements Serializable {

      public UserDetailsBean getUserDetails() {
        return this;
      }

      //...
    }

    Also, note that this inheritance has a disadvantage : it forces you to declare "throws RemoteException" for each method of the Details class. The example thus becomes:

    public class UserDetailsBean implements Serializable{

      public String getUserName() throws RemoteException;
      public setUserName(String name) throws RemoteException;

      //...
    }

    Finally, the last problem with this is that if you want to use CMP, the fields in the Details class must be made public, which allow anyone to bypass the accessors (and thus the validation in these accessors).

    JB.
  13. To make it clearer[ Go to top ]

    Jean-Baptiste,

        Actually, even if you do inherit from your details object, in getUserDetails, you CANNOT return a reference to this (or even (UserDetailsBean)this). I have tried and this generates errors (in Weblogic anyway).

         You are right that IF you inherit from your bean, you will have to throw RemoteException from each method. Infact, if you use an isModified pattern, you will also have to move this logic into the details bean, or you could (my preferred solution) actually implement all the setters of the details bean, and delegate all calls to super.setXXXX(). In this case you would no longer need to put any EJB specifc exceptions/etc in the details bean, since you are delegating calls to it from the entity bean.

         Although it may seem like extra code, this still allows you to keep you validation data in your details object and encapsulate ejb specifc semantics into your entity bean.

    thanks!

    Floyd
     
  14. To make it clearer[ Go to top ]

    Floyd wrote:
    Actually, even if you do inherit from your details object, in getUserDetails, you CANNOT return a reference to this (or even (UserDetailsBean)this). I have tried and this generates errors (in Weblogic anyway).

    I answer:
    It seems to me like a Weblogic problem. I haven(t found anything in the specs saying that You could not do that. To me, since the method signature returns a UserDetailsBean, which is Serializeable, and not Remote, the method must return the object by value. I use this all the time in Inprise Application Server, and it works like a charm.

    Floyd also wrote:
    In fact, if you use an isModified pattern, you will also have to move this logic into the details bean, or you could (my preferred solution) actually implement all the setters of the details bean, and delegate all calls to super.setXXXX()

    I answer:
    To me, the isModified pattern used by Weblogic is a bad pattern. In the EJB world, this should be managed automatically by the container, or at least in a declarative way (set a method as read-only in the DD). Using Inprise Application Server, the container can automatically detect which fields of the bean have been modified, and only update these ones in the database.

    Some patterns work better with some AppServers...

    Regards.
    JB.
  15. To make it clearer[ Go to top ]

    It might be a weblogic problem, but in any case, it's not nice to return instances of your bean to the client - it means they have to have the bean class on their classpath, which is a bit ugly. What happens if the client decides to call ejbFindByPrimaryKey? boom! It also throws away the advantage of beans that the interface and implementation are decoupled; with classic beans, you can replace a CMP bean implementation with a BMP one, or move from a JDBC-backed BMP implementation to one backed by more abstract data access components, all just by changing some options in the deployment and without having to have one classname for multiple implementations. Okay, so maybe not many people take advantage of this ability, but it's an aesthetic thing :).

    What we tend to do at Synomics (all three of us) is break it down a bit further; i posted about this to a JDC forum, by putting a document on the web. Basically, we add a business interface, then make the details (which we call value) class inherit from it, make the bean remote interface descend from it, and then make the bean inherit from the value class. The point of this is that if you have a variable of the type of the business interface, it can point to a value class or a remote interface to the bean. Or a cacheing proxy class, if you want to bring one in.

    Oh, and we have a finder session bean which makes instances of the details class by going direct to the database, sidestepping all that ejbLoad()ing; it's a bit unclean, but it's faster.

    Re the isModified thing; some business methods may or may not change the state of the bean - consider an Account bean with an overdraftLimit field and a boostOverdraftLimit method; if the value passed to the method is smaller than the existing value of overdraftLimit, it shouldn't update it. How do you explain this to the container? You can't, so you'd have to declare that method as a mutator, and you'd get unnecessary ejbStore()s. I would say that the best option is to make both available: the container keeps a dirty flag for the bean (cleared by ejbStore); some methods are declared as setting it in the DD, some set it by a call in the code.
  16.     I am really impressed with some of the great ideas people in this thread are expressing, and I would like to encourage you to write them up as patterns and post them in our repository.
        The more patterns we can accumulate, the more we can help other developers code intelligently, and avoid the problems that made us trip and have to come up with these patterns in the first place!

       Thanks everyone!

    Floyd
  17. To make it clearer[ Go to top ]

    Tom wrote:
    It might be a weblogic problem, but in any case, it's not nice to return instances of your bean to the client - it means they have to have the bean class on their classpath, which is a bit ugly.

    I answer:
    I agree completely. BTW, I've thought about extending the pattern a little bit:
    - make the value class implement Cloneable
    - implement the clone method this way:
        public Object clone() {
          ValueClass clone = new ValueClass();
          clone.field1 = this.field1;
          clone.field2 = this.field2;
          ...
          return clone;
        }
    - implement the getValue method this way:
        public ValueClass getValue() {
          return (ValueClass) this.clone();
        }

    It doesn't require much additional code, and avoids transporting the bean class to the client.

    Tom also wrote:
    Basically, we add a business interface, then make the details (which we call value) class inherit from it, make the bean remote interface descend from it, and then make the bean inherit from the value class. The point of this is that if you have a variable of the type of the business interface, it can point to a value class or a remote interface to the bean. Or a cacheing proxy class, if you want to bring one in.

    I answer:
    I also use a business interface, but I don't make the value class implement it. The bean class implements it and extends the value class. There are two reasons for that:
    - the bean could contain business methods that don't make sense in the value class
    - I think it can be confusing for a client to deal with an object without knowing if it's local or remote.

    BTW, I just realized that it was now deprecated to throw RemoteExceptions in the bean class. This means that the Value class methods (and the other bean methods) don't need to throw RemoteException. That's great, because the client doesn't have to catch them unnecessarily when dealing with a local value object.

    Finally, Tom wrote about fast finders in a session bean and about methods that sometimes modify the state and sometimes not.

    I answer:
    You should really look at Inprise Application Server. Indeed, it can automatically detect if the state has been modified or not (and thus bypass the database update), without needing an additional isModified method. It is also able to update only the modified fields, instead of all the bean state.
    Moreover, it can load the bean state during a CMP finder, even for a multi-finder. Only one database call is made to load all the beans. Using this, your custom finder, using JDBC code, could become unnecessary (unless the ejbLoad method is complex).

    Regards.
    JB.
  18. In the same way that you can have a Entity bean refer to another "child" entity bean to create a representaion of a 1-m relationship, could you also have the detail object that is returned by the "getDetails" method of the "parent" entity bean hold a reference to the detail object that is returned by the "getDetails" method of these "child" entity beans? In this way any aggregate entity beans could return one aggregate detail object in one network trip.

    The getDetails method in the parent entity bean would be responsible for calling the child entity bean 's getDetails method and placing it into the parent's getDetails object. Kind of like the following code that would appear in a "parent" entity bean.

    private Vector mChildEntities = new Vector();
    .....
    /*the vector would get filled when this bean is loaded by the container according to relational schema */

    ParentDetailOb getAllDetails(){
       DetailOb pParentDetails=new ParentDetailOb ();
       pParentDetails.setProperty1(getProperty1())
       pParentDetails.setProperty2(getProperty2())

       ...
       for(Iterator i= mChildEntities.iterator(); i.hasNext );i.next())
           {
             int piChildIndex=0;
             pParentDetails.setChildDetails(piChildIndex++,i.getAlldetails());
           }

        return pParentDetails;
      }


    This would assume you are not using lazy instantiation because maybe you have a requirment for the complete graph of the object when using the getDetails method. Alternatively maybe you could have a getAllDetails method that would return the aggregate details object I mentioned above and a regular getDetails method that would return the same object but with null references to the "child" detail objects.
        I would like to have all my bean extend from some sort of "Aggregate" bean and put this code there. I would then extend this method for each of my entity Beans and call Super.getAllDetails(). if the entity contained any "child" entity references. (Sort of like the composite pattern.) Is this idea reasonable? I would appreciate any thought/comments or suggestions as I am relatively new to the ejb world.
    thanks
    Jeff
  19. Jeff,

       I think this is a good strategy, worthy of being posted as a separate pattern in our patterns repository Jeff.

       That way, comments on your pattern won't be mixed with comments on this original thread.

    thanks,

    Floyd
  20. To make it clearer[ Go to top ]

    Anyone has an idea how to synchronize value (detail) objects between client and server once they were sent to the client? Client to server synchronization looks simple as a client just have to send changed value object to server (or better just a things that were modified thus avoiding network overhead). How about server to client synchronization? What if value object was sent to client and the server data changes? Does the server need to keep track of all value objects sent to the particular clients and inform all of them when change was done so they can update their value objects?

    Ivan

    JBZ how it's going? ;)
  21. To make it clearer[ Go to top ]

    I think one sensible, safe solution (although perhaps not relevant in all cases) is to make the value object immutable (i.e. no setters) so that client developers are not given the impression that any 'real' data can be changed by manipulating the value object. The data is squirted into the value object in the constructor. Any updates would then be carried out by methods on a session bean wrapping the entity, or other standard techniques.

    Also, I would not restrict the value object to just being a container for data - it could also be given more sophisticated query behaviour. For instance, if you use a value object representing addresses, give it operations returning formatted versions of the address and so forth. Pretty standard stuff, I know, but when things are referred to as 'data objects' some people take it a bit literally. These are just vanilla Java objects.

    Finally, why does the original poster (sorry, I can't see the name at this point in my post) refer to the value object as a bean? Doesn't this just create confusion, when the whole point is distinguishing it from an EJB? Can't we just go back to calling them 'objects'?

    Matt

  22. To make it clearer[ Go to top ]

    Finally, why does the original poster (sorry, I can't see

    >the name at this point in my post) refer to the value
    >object as a bean?

       I refer to it as a bean because the value object is just a data holder with getters and setters. Java Beans follow a similar conventions. ie: for attribte xxx, you would have a getXXX and setXXX methods.. Thus for those familiar with a Java Bean is, calling the value object a bean would make things clearer in my opinion, but I can see where the confusion would arise if the reader is not familiar with JavaBeans.

    Floyd
  23. To make it clearer[ Go to top ]

    I agree with Floyd, if a java class uses getters and setters and it is serializable then it fits all the requirements to bea java bean . The various j2ee books out there seem follow the same convention.
    Jeff
  24. Detail - Entity Bean Synchronization[ Go to top ]

    I've been playing with this pattern a bit and keep running into one aspect that is giving me heartache. For simple object hierarchies, sync'ing up calls to the detail objects setters is pretty straight forward. However, with complex object hierarchies, (multiple 1-1, 1-M, etc), this seems to get very ugly, very fast. In trying to keep straight in the 1-M relationships, what has been added, removed, or simply changed, can get messy. How have people been dealing with this? I've tried having a session bean handle this as a form of mediator and also tried having the EJB take a detail object as an argument to a method or constructor. Both have been messy. Thoughts?

    Bill
  25. To make it clearer[ Go to top ]

    Tom,

    I've read the code you you mentioned on that web page. It's really good. One question though, why don't you have the CustomerValue class implement the CustomerRemote directly? What value does the base Customer interface add?

    It should be ok to provide a local implementation of that remote interface. Thanks.

    Ash
  26. To make it clearer[ Go to top ]

    I can't speak for Tom, but it appears to me that having the Value class implement the Customer interface and not CustomerRemote allows for the base interface and the Value class to not make any references to any of the EJB packages. In essence, you have a layer that truly knows nothing about the persistent components. The only part of this that is a little ugly is that the methods in the base interface must throw RemoteException.

    One question regarding that. Someone mentioned earlier that throwing RemoteException was no longer required. What are the details of this? Is this an EJB 2.0 thing?

    Bill
  27. To make it clearer[ Go to top ]

    Reply for a post a while ago...

    The EJB 1.1 spec states that throwing of RemoteExceptions is deprecated from business methods. Throwing of RemoteExceptions are reserved for system exceptions. Business methods should instead throw application exceptions or runtime exceptions which cause the application server to rollback the transaction etc.

    Check out section 17.2 of the EJB 2.0 spec (possibly the same section in 1.1, I just don't have it with me at the moment)
  28. To make it clearer[ Go to top ]

    I have go through Tom Anderson's document. It's pretty good, but I still have some comments:

    in the sessionBean, I don't see any needs to implement the findValueByPrimaryKey and findProxyByPrimaryKey, since these functions have been done in the EntityBean. I think, in the sessionBean, the most important method should be:

    public Vector findAllValues();

    Because this method provides bulk read to the database.

    Any comments?
  29. To make it clearer[ Go to top ]

    The correct code is:


    public UserDetailsBean getUserDetails() {
        return entityContext.getEJBObject();
      }

  30. Problem with Details Pattern[ Go to top ]

    We are using Weblogic server 5.1 and our interfaces and classes looks like this.

    //This interface has business methods
    public interface IBusiness
    {
    public Object getDetails() throws java.rmi.RemoteException;
    }

    //This interface has Detail object get/set methods
    public interface IUserDetails
    {
       public Integer getUserId();
       public Integer getCompanyId();
    }

    //This class implements IUserDetail interface
    public class UserDetails implements IUserDetails, java.io.Serializable
    {
    protected Integer iUserId;
    protected Integer iCompanyId;

       public Integer getUserId()
       {
    return iUserId;
       }
      public Integer getCompanyId()
       {
    return iCompanyId;
       }

    }

    //Remote interface
    public interface User extends IUserDetails, IBusiness, javax.ejb.EJBObject
    {
       public Integer getUserId()
         throws java.rmi.RemoteException;
       public Integer getCompanyId()
         throws java.rmi.RemoteException;
    }

    //Bean class
    public class UserBean extends UserDetails implements IBusiness, javax.ejb.EntityBean
    {
    public Object getDetails()
    {
    //implementation
    }
    //other ejb callback methods
    }

    When building the bean ejbc is throwing the following error.

    ERROR: Error from ejbc: [9.2.7] In EJB UserBean, method java.lang.Integer getUserId() defined in the remote interface must include java.rmi
    .RemoteException in its throws clause.
    ERROR: Error from ejbc: [9.2.7] In EJB UserBean, method java.lang.Integer getCompanyId() defined in the remote interface must include java.rmi
    .RemoteException in its throws clause.
    ERROR: ejbc found errors


    What is the reason and what is the solution?
    Note:
    Even if we delegate the get/set calls to super class we get the same error.
  31. Clarification[ Go to top ]

    Floyd -

    I've read through all the patterns in this site and serveral other sites and I would like you to clarify your terminology. Are Detail objects and Value objects synonymous? If not, how do they differ?
  32. Clarification[ Go to top ]

    Daniel,

      They are perfectly synonymous. There are many names for this pattern, I just chose to use the name I read in the original article I learned this pattern in.

    Floyd
  33. Over All Design Pattern[ Go to top ]

    Hi,

    I would suggest not inheriting the Value Object into The Entity Bean, if it is going to cause implementation issues in EJB 2.0.

    Creating an immutable Value Object(a very good idea) and passing it to Client does make good sense. This solves the Original purpose of reducing the network traffic for this design pattern.

    As suggested previously this object can have smart get methods like getBySorting or getAfterCalculatingX.
    Doing lazy loads in the Data Object will give problems in some cases where transactions are being taken into consideration.

    Entity Beans are already an Object representation of Data with some Logic as well. Value Object does serve a purpose but should it replicate the whole of Entity Bean(stripped of it's Callback methods).
    If I m wrong please do correct me.

    Parikshit
    parikshitpol@hotmail.com
  34. Article online[ Go to top ]

    I agree. Throwing RemoteException from each method doesn't seem right. plus your business objects must now inherit from entity beans, rather than some other class, perhaps linked to your own persistence framework.

    At www.javareport.com I describe an approach which not only allows you to generate single Details objects, but graphs of them automatatically. The details objects and business objects are generated from a single schema, and Java reflection is used to map between them, so there is no extra coding required.

    Check it out at
         http://www.javareport.com/html/from_pages/feature.cfm

    Jeremy
  35. Article online[ Go to top ]

    Hi! Jeremy,

    > Check it out at
    > http://www.javareport.com/html/from_pages/feature.cfm

    The provided link does not seem works. Can you point out the javareport issue number that your artical is on?

    Henri Chen.
    henri_chen@yahoo.com
  36. To make it clearer[ Go to top ]

    Question about the code:
    public class UserDetailsBean implements Serializable {

      public UserDetailsBean getUserDetails() {
        return this;
      }

      //...
    }

    If you return "this", does it increase coupling between your presentation tier?
  37. Details Object[ Go to top ]

    How (if at all) is the advice in this pattern affected if the "Sessions Bean Wraps Entity Beans"-pattern is applied? (That is, if the only clients to entity beans are session beans that access one or more entity-beans within single transactions, implementing "coarse grained" business logic).

    The answer to this may perhaps depend on whether the beans all run in one container or not. I would think that sensible containers are able to use non-remote calls between beans running in the same container (or is this misguided?) Anyway, I realize that this would address implementation details, so maybe it is irrelevant to my question.
  38. Hi,

    I'm currently designing an EJB using the Detail Pattern, and I'm evaluating both BEA Weblogic 5.1 (with SP4), and Inprise App Server 4.

    I've been able to deploy it without problems on IAS, but when I try it create the ejb jar using Weblogic's deploytool, I get an error saying " ".

    Has anybody encountered this problem before?

    Thanks.
  39. Sorry,

    I left out the error message in my last post. Here it is:
    "java.lang.NoClassFoundException: No suitable home found for bean".

    I've tried making the Detail Object serializable, and making the methods throw RemoteExceptions, but the problem still persists in Weblogic.
  40. I have encountered the exact same problem with using the deploy tool for BEA. I am actually in the middle of getting some answers from technical support on that very issue. I have sent them a jar file of my own and waiting for an answer.

    However, in the meantime, I have actually edited the XML files myself and compiled and deployed the EJB manually. If you go to the documentation on BEA's website for using the weblogic.ejbc tool, you can generate and compile the stubs all in one step yourself without using the tool. After that, you can use the command line deploy tool to deploy the jar or just modify the weblogic.properties file for permanent deployment.

    My guess is that their tool cannot "reflect" or understand the extra inheritance layer in the bean. For example, I was trying to use the patterns mentioned here and it didn't work. Also, I was trying to extend their BSC smart components--which make up their Buy Beans demo--and it didn't work, either.

    Here is the exact syntax for generating and compiling the stubs:
    java weblogic.ejbc -keepgenerated -compiler javac myEJB.jar myEJB_deployable.jar

    Hint: Make sure you have your environment classpath setup properly:
     c:\weblogic\lib\weblogic510sp3.jar;c:\weblogic\classes;c:\weblogic\lib\weblogicaux.jar;c:\j2sdkee1.2.1\lib\j2ee.jar;

    Good luck!
    Ozzie
  41. Details Object[ Go to top ]

    One comment w.r.t to the bean implementation inheriting from the details object. As good as the idea might be for EJB 1.1 it will not work for EJB 2.0 - style beans. That is because EJB 2.0 bean implementation is an abstract class with abstract getters and setters.

    My opinion is that to ease the future transition one should not go into a habit of making the bean implementation inherit from the detail object.

    Also, seems to me that this is not such a great idea from the conceptual point of view as the proper conceptual model would have bean implementation aggregating the detail object, not inheriting from it.

    Regards,

    Bartek
  42. Details Object[ Go to top ]

    Bartek,

      From a purist OO perspective, I agree that aggregating the details object may be better than inheriting from the details object (after all, and EJB is not a special kind of details object, although one might say that the entity bean is a persistent version of the details object).

      Inheriting from a details object is not a fundamental part of the details object pattern, just a peripheral convenient use of it.

      I wasn't aware of the ejb2.0 restriction you mention. Can you please elaborate on that?

    Floyd
  43. Details Object[ Go to top ]

    Floyd,

    I was referring to the fact that in EJB 2.0 the
    CMP entity bean should have all getters and setters
    for every container-managed field defined as abstract
    methods. That is because when you deploy the bean,
    the persistence manager should generate the actual
    class and provide the getters and setters. That
    is certainly very different from EJB 1.1 where it
    was enough to define the CMP fields as public
    attributes of the bean implementation class.

    Now, clearly inheriting from the detail object that
    provides the implementation for the setters and getters
    is no longer a valid thing to do as we should leave
    getters and setters abstract.

    Regs,

    Bartek
  44. Details Object[ Go to top ]

    Hi,

    The discussion is evry informatoive and this is the one i'm looking for..
    I need u'r help experts..

    We need to have a java value object that shuld be passed between client(applet)
    and ejb

    What r the pros and cons in the following two designs ..?

    Inheriting Java Object:

    By Inheriting the Java Object from the entity bean, the client will get the java object
    thru remote interface..
    Here the attributes of java object shuld be public..

    Using Ejb2.0:

    setting values of the entitybean attributes using abstract set and get methods of
    ejb2.0 specification.
    Here we have attributes of java value object as private which is one of our requirements.

    The Entity bean has the following methods..

    abstract public void setId(java.lang.String val);
    abstract public java.lang.String getId();

    abstract public java.lang.String getNumber();
    abstract public void setNumber(java.lang.String val);

    abstract public void setName(java.lang.String val);
    abstract public java.lang.String getName();


    public String ejbCreate(DataObject obj) throws CreateException
    {
        log("ejbCreate( )");

    setId(obj.getId());
    setName(obj.getName());
    setNumber(obj.getNumber());
        return null;
    }

    public void setJavaObject(DataObject obj)
    {

    setName(obj.getName());
    setNumber(obj.getNumber());
    }

    public DataObject getJavaObject()
    {
    DataObject det = new DataObject();
    det.setName(getName());
    det.setNumber(getNumber());
    return det;
    }

    Where DataObject is a simple Value Object having attributes and get and setMethods..
    Is the above design with EJB2.0 has any disadvantages..?

    Any help will be highly appreciated..

    Thanks
    Amie
  45. Details Object[ Go to top ]

    Hi. I am developing a EJB solution using the Details Object or the Value Object pattern. I am using TOPLink for Weblogic 2.5.1 GA for entity bean persistence.

    I have a business object called Customer with getters ans setters for the attributes. The remote interface CustomerRemote extends the business interface and has methods like login(). I have a details Object CustomerValue which implemnts the business interface. The EJB class CustomerBean extends the value class, CustomerValue and has a method called getCustomerDetails() which looks like this.
                CustomerValue myClone = new CustomerValue();
                myClone.setFirstName(this.getFirstName());
                myClone.setLastName(this.getLastName());
                myClone.setEmailAddress(this.getEmailAddress());
              myClone.setPhoneAreaCode(this.getPhoneAreaCode());
                myClone.setPhoneNumber(this.getPhoneNumber());
                myClone.setLoginName(this.getLoginName());
                myClone.setPassword(this.getPassword());
                //myClone.setCustomerId(this.getCustomerId());
                return myClone;

    So I invoke the login method from the client which returns a reference to the EJBObject. Then I do a getCustomerDetails() to get the value class.

    The problem is, its correctly looking up for the entity bean when I say findByLoginName(String aLogin). But when I do a getCustomerDetails(), its inserting one more row
    into the Customer table with the same data that was got from the findByLogin() method.

    I mapped the CustomerBean class to the Customer table in the Builder and the CustomerValue is unmapped.
    Is there some configuration needed in the TOPLink Builder for the inheritance between CustomerValue and CustomerBean.


    I have all my getters,setters and the attributes in the value class. Should I duplicate the attributes in the bean class also. I think I am being forced to have the setters in the value object for instantiating a new object. The client would just be accessing the getters.

    Please suggest me how to do this.
  46. Details Object[ Go to top ]

    Pradeep, it looks like TOPLink thinks that the row that represents your Customer does not exist. You can try calling TOPLink.Public.Sessions.ServerSession.logMessages() to switch on TOPLink diagnostic tracing. This will show you the SQL that it is executing against the DB.

    Also, make sure that the column in your customer table that represents the primary key ( LoginName ?) has a unique constaint on it. The stack trace produced by TOPLink when it tries to insert the duplicate row when the constraing is in place should help you diagnose where things are happening.

    Tim
  47. Details Object[ Go to top ]

    Oh, and Pradeep, you should really be posting these type of questions to the appropriate forum, i.e., "Enterprise Java Beans Troubleshooting Forum" as this has nothing to do with this pattern per se.

    Tim
  48. Details Object[ Go to top ]

    Hi everybody,

    I am new in this thread.
    Is this pattern applied on Session Bean (stateless)? If so, how do you get the real benifit when you dont have any state in your objects (stateless session bean)?

    thanks,
    fa.
  49. Details Object[ Go to top ]

    I am impressed by your pattern . It realy will give
    the improvement to performonce . I think calling the object
    which carries the Entity Bean's state as " State object " would be more meaning full , because it contains the state of the entity bean. One more think I want to add here is
    when we use the XML for Data representation , keeping
    one method so that it will return the object state a
    XML format will be more helpful while we do session bean coding , the reverse can to for Converting XML to state
    object. I mean readToXML() and WriteFromXML() methods
    we can maintain as madatory in the Sate object.
  50. Details Object[ Go to top ]

    This actully reduce the serialization and deserialization
    to much and improve the performance.