Page 1 of 11 123 ... LastLast
Results 1 to 10 of 102

Thread: DAO Reference Inside an Entity Domain Object?

  1. #1
    Join Date
    Sep 2004
    Location
    Vancouver, BC, Canada
    Posts
    135

    Default DAO Reference Inside an Entity Domain Object?

    I have an entity domain object that has a large collection of child entity domain objects. I have to implement an operation (let's call the operation getSum) for the parent that involves filtering out most of the child objects and then summing a field in the remaining objects and returning the sum.

    The database could hold hundreds of thousands of the child objects but for any single invocation of this operation, we are usually only interested in a small percentage of those child objects. Therefore, rather than loading all of the child objects into memory (in a Collection that lives in the parent) and filtering them there, I think it would be better (performance wise) to filter them on the database server. So, I have created an operation in a DAO that submits a datbase query that does this filtering and the calculate the sum.

    For layering purposes, I do not want to give the client direct access to the DAO. Instead, the client will call getSum on some object and that object will then delegate to the DAO. So, my question is, WHICH object should expose getSum to the client? Should it be the parent object or some service object? For example:

    Should I do this?
    Code:
    class MyParentEntity
    {
      private MyDao dao;
      
      public void setDao(MyDao dao)
      {
        this.dao = dao;
      }
    
      public int getSum(FilteringParams params)
      {
        return dao.getSum(params, this);
      }   
    
      // other operations
    }
    OR this?
    Code:
    class MyServiceImpl implements MyService
    {
      private MyDao dao;
      
      public void setDao(MyDao dao)
      {
        this.dao = dao;
      }
    
      public int getSum(FilteringParams params, MyParentEntity parentEntity)
      {
        return dao.getSum(params, parentEntity);
      }   
    
      // other operations
    }
    In this first case, the client will call MyParentEntity.getSum(). In the second case, the client would instead call MyService.getSum(), passing an instance of MyParentEntity as a parameter.

    Putting the operation into MyParentEntity seems more natural because the operation involves an instance of MyParentEntity. On the other hand, it seems unnatural to give an entity object access to a DAO.

    Any advice?
    Cheers,
    Joe
    "All your bean are belong to us" - Spring Framework's IOC Container

  2. #2
    Join Date
    Oct 2004
    Location
    Herndon, VA, US
    Posts
    648

    Default

    I have also been exploring (and justifying) the first approach, because having to go through a service API to get child DOs of a parent DO will almost unavoidably lead to an anemic domain model.
    --Jing Xue

  3. #3
    Join Date
    Sep 2004
    Location
    Vancouver, BC, Canada
    Posts
    135

    Default

    manifoldronin, thanks for your reply. It's nice to know that I am not the only one wrestling with this issue. So I guess I'm not a dummy after all...

    Now, correct me if I'm wrong...from my reading of Spring books, sample code, documentation and forum topics, I get the feeling that many Spring folk usually would use the service to get the child domain objects. Why do they seem to prefer the service approach?

    I recently got the idea for the first approach (i.e. giving a DAO reference to the parent) from the book Domain-Driven Design by Eric Evans, who is apparently a colleague of Martin Fowler. Specifically, the idea came from pages 177-178, where he talks about refactoring a child collection into a query.

    It seems to me that your comment about "anemic domain model" caused by using the service is bang on. In fact, Fowler talks about the AnemicDomainModel anti-pattern on his website. His comments seem to describe the situation here.

    One thing I do like about the service approach is that it makes it very easy to see where transactions are demarcated. If I put some DAO access into domain objects, will I have to sprinkle transactional demarcation all over the place? If so, is this a bad idea? In other words, is there anything wrong with making a method in a domain object transactional?

    By the way, I HIGHLY recommend the aforementioned book. In particular, I found Evans notion of Aggregates to be particularly helpful.
    Cheers,
    Joe
    "All your bean are belong to us" - Spring Framework's IOC Container

  4. #4
    Join Date
    Oct 2004
    Location
    Herndon, VA, US
    Posts
    648

    Default

    Quote Originally Posted by cyboc
    manifoldronin, thanks for your reply. It's nice to know that I am not the only one wrestling with this issue. So I guess I'm not a dummy after all...
    Same feeling here... (but then, it's still fairly suspicious that only the two of us are talking about this idea here... :wink:
    Quote Originally Posted by cyboc
    Now, correct me if I'm wrong...from my reading of Spring books, sample code, documentation and forum topics, I get the feeling that many Spring folk usually would use the service to get the child domain objects. Why do they seem to prefer the service approach?
    I can think of a few arguments for the service approach(and counter arguments respectively):

    - As you said, it's easier to see the transaction boundary. But I think it's a myth, because a service method does not necessarily represent the corresponding transaction boundary. It's all up to the transaction declaration outside the service method. It's no easier nor harder to tell the transaction boundary when doing the logic from within the domain objects.

    - Domain objects should not know about external interfaces such as DAO's. I agree in principle, but DAO's should not be considered external, because they are abstract interfaces you define and have total control over.

    - Performance concerns and implementation issues, i.e., domain objects are usually instantiated by an ORM tool (hibernate for example), so how and when to inject the DAO could be a problem. Also, a DAO being stateless would be a waste of memory to be injected into each domain object. I think these are valid concerns and have been looking into using AOP to solve these problems.

    Quote Originally Posted by cyboc
    I recently got the idea for the first approach (i.e. giving a DAO reference to the parent) from the book Domain-Driven Design by Eric Evans, who is apparently a colleague of Martin Fowler. Specifically, the idea came from pages 177-178, where he talks about refactoring a child collection into a query.

    It seems to me that your comment about "anemic domain model" caused by using the service is bang on. In fact, Fowler talks about the AnemicDomainModel anti-pattern on his website. His comments seem to describe the situation here.
    Yes, that is the very source where my thoughts came from, too.
    --Jing Xue

  5. #5
    Join Date
    Aug 2004
    Posts
    1,905

    Default Well I am thinking of it too, but...

    The fundamental question is whether you consider your "domain object loader" (your DAO) as part of the domain object, and I don't think it is.

    The DAO itself is a service, so I don't think it should live in the domain object.

    The domain model is not aneamic just because it requires collaborators. It is perfectly OK to pass collaborators at runtime, so you would have

    public int getSum(ChildEntityLocatorStrategy, FilteringParams)

    where ChildEntityLocatorStrategy was an interface which retrieved the relevant entities. Of course, there would be a DAOChildEntityLocatorStrategy which simply called dao.getSum(params, parent).

  6. #6
    Join Date
    Sep 2004
    Location
    Vancouver, BC, Canada
    Posts
    135

    Default

    yatesco,

    Thanks for your comments. Just to clarify, is this how you see the code?
    Code:
    class MyParentEntity
    {
      public int getSum(ChildEntityLocatorStrategy childLocator, FilteringParams params)
      {
        childLocator.getSum(params, this);
      }
    
      // other operations
    }
    
    interface ChildEntityLocatorStrategy
    {
      public int getSum(FilteringParams params, MyParentEntity parentEntity);
    }
    
    class DAOChildEntityLocatorStrategy implements ChildEntityLocatorStrategy
    {
      private MyDao dao;
     
      public void setDao(MyDao dao)
      {
        this.dao = dao;
      }
    
      public int getSum(FilteringParams params, MyParentEntity parentEntity)
      {
        return dao.getSum(params, parentEntity);
      }   
    
      // other operations
    }
    Cheers,
    Joe
    "All your bean are belong to us" - Spring Framework's IOC Container

  7. #7
    Join Date
    Sep 2004
    Location
    Vancouver, BC, Canada
    Posts
    135

    Default

    Quote Originally Posted by manifoldronin
    domain objects are usually instantiated by an ORM tool (hibernate for example), so how and when to inject the DAO could be a problem. Also, a DAO being stateless would be a waste of memory to be injected into each domain object. I think these are valid concerns and have been looking into using AOP to solve these problems.
    Yatesco's idea seems to solve the problem of how to inject the child loader collaborator (either a dao or his strategy object) into the parent domain object -- he does it with each invocation of getSum. While this is not as transparent as getting the IOC container to inject it when the domain object is instantiated, it does work in the situation where Hibernate (instead of the IOC container) manages the domain object. Having said that, the AOP idea would be nice if you can get it to work with Hibernate-managed domain objects.
    Cheers,
    Joe
    "All your bean are belong to us" - Spring Framework's IOC Container

  8. #8
    Join Date
    Oct 2004
    Location
    Herndon, VA, US
    Posts
    648

    Default

    Yatesco's approach is definitely valid. However here's what I don't like it about.

    It forces the consumer of the domain object to worry about providing a strategy to retrieve part of the domain object which should have been the domain object's own concern. E.g., in a typical parent/child situtation, the domain object Parent should provide a simple JavaBean getter method, getChildren(), which returns all the children. Or the Parent could choose to provide getChildIterator() for more efficient operations. Either way, how the children are retrieved is not of the caller's concern.

    As already implied, it would also break the JavaBean convention and encapsulation. Now a domain object would have two different kinds of getters for different kinds of properties - one for those simple properties, and another for those requiring complex handling.

    Last but not the least, passing a strategy in each call may be an overkill in most cases, because this strategy rarely changes at runtime.
    --Jing Xue

  9. #9
    Join Date
    Sep 2004
    Location
    Vancouver, BC, Canada
    Posts
    135

    Default

    manifoldronin -- good points.

    yatesco -- rebuttal?

    (btw, good discussion, isn't it?)
    Cheers,
    Joe
    "All your bean are belong to us" - Spring Framework's IOC Container

  10. #10
    Join Date
    Sep 2004
    Location
    Vancouver, BC, Canada
    Posts
    135

    Default

    Are any of the heavyweights (e.g. Rod and Colin) going to chime in on this discussion?
    Cheers,
    Joe
    "All your bean are belong to us" - Spring Framework's IOC Container

Similar Threads

  1. Replies: 2
    Last Post: Oct 10th, 2005, 05:12 PM
  2. Loosing my SecureContext
    By sklakken in forum Security
    Replies: 3
    Last Post: Jul 21st, 2005, 01:44 PM
  3. Other Hibernate DAO LazyInitializationExceptions
    By bernardsirius in forum Data
    Replies: 5
    Last Post: Feb 18th, 2005, 04:09 PM
  4. Replies: 9
    Last Post: Feb 8th, 2005, 09:25 PM
  5. Replies: 0
    Last Post: Jan 6th, 2005, 08:19 AM

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •