Discussions

J2EE patterns: Dynamic Entity Model

  1. Dynamic Entity Model (5 messages)

    The problem is old and many solutions have been provided. As for other patterns, the challenge is to solve a recurring software problem, or more specific the recurring problem of providing an implementation for an arbitrary design of a data layer. We face the same problem of implementing the same attributes with different names and types, the same entities with different names, attributes and relationships and the same relationship types with different cardinalities and constraints.

    New solutions are rarely innovative. Usually it is a combination of further refinement of existing patterns or designs and a composition of existing patterns in new ways to achieve new and enhanced functionality. This solution use both refinement and composition.

    The Dynamic Attribute pattern solves the problem of a dynamic transfer of arbitrary data at a fine grained level. The Proxy system pattern, acting as an agent between the client and the entity model, solves the problems of enforcing consistent semantics for data access and model traversal. The Dynamic Entity Model solves the problem of transferring entity data and performing traversal by using the Dynamic Attribute as a finer grained pattern, and the Proxy pattern for short, as a synergistic pattern. The patterns are organized into an overall architecture for the data layer. In addition a primary key generator pattern is used as a finer grained pattern for identifying entities in a unique way.

    By using a dynamic model for the data layer combined with a proxy pattern acting as a delegate, translator and dispatcher for the entity model we achieve some important functionality:

    • The conceptual component model for the data layer can be
      described as a set of Java interfaces and let the
      Dynamic Entity Model pattern execute the model based on
      the information content of the interfaces. No
      implementation of the model is needed.
    • Navigation between entities is done in an OO fashion,
      without implementing the traversal between entities.
    • By defining general accessor to attribute and entity
      types and values and leave the management of these up to
      the implementation, existing interfaces do not
      necessarily have to be changed when new attributes or
      entities are added. Only clients that rely on these
      newly defined model elements need to be enhanced.
    • Clients have easy runtime access to a formal description
      of the model, as meta data.

    First the pattern is described from a “usage” point of view, and lastly the most important implementation aspects are commented.

    From e.g. an UML or an ER model a set of Java interfaces may be generated or coded as shown in the following example (exception handling and imports are removed from the source). Note that these interfaces are all part of the client side:

    public interface Tree extends EntityModel {
      public PrimaryKey getTreePk();
      public Integer getName();
      public void setName(String name) ;
      public Collection getTreeFk(Element treeElem);
    }

    public interface Element extends EntityModel {
      public PrimaryKey getElementPk();
      public ForeignKey getTreeFk() ;
      public void setTreekFk() ;
      public Integer getName();
      public Tree getTreePk();
    }
    The interfaces represent the entities Tree and Element with a 1:M relationship between them. Members define primary keys (treePk, elementPk) , a foreign key (treeFk), ordinary attributes (name) and a 1:M relationship (Collection getTreeFk (Eleement elem). The relationship has a 1:M from Tree to Element and also define an M:1 navigation from Element to Tree (Tree getTreePk()).

    A client may than use this simple Entity model, as seen from the following example, retrieving attribute values and performing a 1:M traversal between the two entities Tree and Element.

      public DynamicEntityClient() {
         Class[] model = {Tree.class, Element.class};
          EntityProxyFactory factory =
            new EntityProxyFactoryImpl(model);
          EntityModelHome treeHome = (EntityModelHome)
             factory.getHomeModel("TreeModel");
          Collection allTree = treeHome.findAll();
          Iterator treeIter = allTree.iterator();
          Element elem = null;
          while (treeIter.hasNext()) {
            Tree tree = (Tree)
              factory.getRemoteModel(treeIter.next());
            log(tree.getName());
            Collection coll = tree.getTreeFk((elem);
            Iterator elemIter =
               coll.iterator();
            elem = (Element) factory.getProxy();
            while (elemIter.hasNext()) {
              elem.getNext(elemIter.next());
              log(elem.getName());
            }
          }
        }

    The DynamicEntityClient get the home interface through the proxy. The simplicity of the interface is possible, because the EntityModel use the same JNDI name across clients. Models are separated by using different model names (here: "TreeModel").

    In addition to provide inter and intra entity search mechanisms, the home interface of the EntityModel operates on the model as a whole and have create members for registering the model and defining the view and scope of the model. Different parts of the model may be registered for each home interface and 1:1 relationships between entities may for instance be provided by letting one interface inherit from another. How to register a model consisting of the Tree and Element interfaces is shown in the first part of the DynamicEntityClient code.
     
    The EntityModel may be used at two levels of abstraction; - The one already sown using interfaces representing the entities; or – By accessing the remote interface of the EntityModel directly through the proxy. As an illustration, the following shows some of the members from the remote interface of the EntityModel. The two modes may also be mixed.

      public interface EntityModel {
         public void setEntity(String entityName,
            Entity entity);
         public Entity setEntity (Class classEntity);
         public Entity getCurrentEntity();
         public Attribute get(String name);
         public void set(String name, Attribute value);
         public Collection traverse(Entity entity,
            ForeignKey foreignKey);
        public Object getNext(Object key);
    }
     
    The model is created by using a create member from the home interface (see create in EntityModelClient example). The entities and the attributes are specified by name. Then by using the remote interface it is possible to add and remove entities and attributes, get/set values and traverse the model.

    As a note, some of the consequences of the pattern is; - proxy overhead; - lack of strong typing; and – cost of maintaining the state of the registered model on the server. With the exception of the overhead method invocation on the proxy introduces, workarounds may be implemented to reduce and limit other implications.

    Some Comments on the implementation.

    The variable “model” lists all entities as an array. Entities may also be added and removed from the model on an individual basis. The proxy forwards these interfaces to the EJB (EntityModel). Reflection is than used for transforming the interfaces to Entity objects. The name of the interface becomes the name of the Entity. Member functions, following the naming conventions from Beans, become attributes. Member functions with parameter or return type of Primarykey or ForeignKey are registered as key and foreign key attributes in their corresponding entity. Traversal functions are transformed to relationships between the entities. The return type or inheritance tree determines whether it is a 1:M or 1:1 relationship. Note that M:M relationships can be reduced to two 1:M relationships or as an enhancement transformed to two 1:M relationships by the EntityModel.

    In sum the interfaces constituting the model is transformed, by a ModelMapper object, to a data structure held by a Model object. A RelationalMapper class transforms the model into SQL statements. The model is stored on the server using JNDI. The assumptions and conventions for the syntax and semantics of the client interfaces (or entities) are design decisions that may be altered or extended, by altering the proxy implementation or providing different proxy implementations based on the same proxy interface for different design decisions.

    The Proxy sits between the client and the EntityModel Bean, and acts as a local cache for data and is responsible for detecting member functions invoked by the client and dispatch these calls to the server. From the client example above the getRemoteModel member is a wrapper for getting hold of a reference to the remote interface. To drill down from a parent entity (Tree) to a child entity (Element) an iterator is obtained by using a get<nameOfForeignkey> (getTreeFk) member of the parent entity (Tree interface), providing the child entity (Element) as a parameter to the member function. Other attributes than foreign keys may also be used as criteria for the traversal. The getProxy function uses the same remote reference as the Tree interface. This means that, when drilling down the path of relationships one has one starting point and all child entities uses the same remote interface. This is possible due to the fact that all interfaces inherits from the remote interface (EntityModel) and the proxy dispatches the invocation on the member functions to generic dynamic entity and attribute members on the server.

    Threaded Messages (5)

  2. Dynamic Entity Model[ Go to top ]

    I'm new to patterns, so some (or all) of my questions, might seem silly.

    1. Could you elaborate on the Proxy pattern?
    2. How will you find out which resulting Entity to serialize, when the state changes by the operations done by the client?
    3. Can this not be further generalized to support multi-entity relationships?
    4. It would be great if you could shed some light on the ModelMapper and RelationalMapper too.

    Thanks,
  3. Dynamic Entity Model[ Go to top ]

    I have written a white paper on the pattern that I can mail to you. I will try to give a short explanation to your questions.

    1. The Proxy Pattern.

    The best reference is the pattern posted in this section by Raffaele Spazzoli called Dynamic Value Object. I used this pattern as a skeleton for my implementation.

    2. How will you find out which resulting Entity to serialize, when the state changes by the operations done by the client?

    If it is a change at the meta level, ): an attribute is removed or added in an entity, this is detected by the member function on the server side, which is invoked by the proxy. By using a version pattern one can distinguish between different versions of an entity. It is a fault to remove an attribute, and then later call (e.g. elem.getName()) a member function through the Java interface (e.g. Element) where it first was defined. It only makes sense to remove an attribute which has been defined in a dynamic way (e.g. create("attrName", "value")).

    3. Can this not be further generalized to support multi-entity relationships?

    If you by this mean e.g. n-ary relationships, yes it can. This should be on my todo list. It is a question of what kind of datastructure the model object should use internally to handle n-ary relationships.

    4. It would be great if you could shed some light on the ModelMapper and RelationalMapper too

    The ModelMapper receives Java interfaces from the client. From the client example:

    Class[] model = {Tree.class, Element.class};
    EntityProxyFactory factory = new EntityProxyFactoryImpl(model);

    The factory object calls a create member on the EJB's home object, with the model array as a parameter. The ModelMapper parse each of the interfaces in turn and adds the entity name, the attributes and the relationships to the model. The interface name becomes the name of the entity, the get/set member functions translates to attributes and member functions returning collections or other interfaces becomes relationships. The Model contains a collection of Entity objects which again contains a collection of Attribute and Relation objects. This is the main datastructure on the server, which hold all Entities and their relations to Attributes and relationships.

    When the home interface is called issuing a search, create or remove function the RelationMapper traverse the "model" datastructure and translates it into a SQL statement before execution. ejbLoad and ejbStore works in the same manner. For optimazation, different SQL statements that not changes between calls are stored internally and exuted over again with maybe different parameters.

    If interested, you can find a description of the Version and Attribute patterns in the book: "EJB Design Patterns" by Floyd Marinescu on this site.

    Eirik
  4. Dynamic Entity Model[ Go to top ]

    Hi,

    I've been working on trying to understand this pattern. I'm not sure if I understand it fully, but have made a half-baked UML model on the same. After the first post I thought I understood a bit of it, but I'm totally lost now :-)

    It would be great if you could email me that white paper you wrote and some sample code to manav at zycus dot com

    Warm Regards,
    Manav.
  5. Dynamic Entity Model[ Go to top ]

    I'am new to design pattern, so please send that white paper or an implementation to andreas dot reitsam at sigel dot de

    Best regards,
    Andreas
  6. Dynamic Entity Model[ Go to top ]

    I'm also confused.. Can you provide more samples ? Seems very interesting