Announcement Announcement Module
Collapse
No announcement yet.
Should Business Objects have References to DAOs? Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Should Business Objects have References to DAOs?

    Hello,

    Follow a successful previous thread, I'd like to open a new thread. In the <a href="http://forum.springframework.org/showthread.php?t=9846">previous architectural thread</a>, we talked about what it means to move business logic into business objects, where business objects are brought to life by Hibernate, but wired by Spring.

    I've got a use case that illustrates the need for the business object to have a reference to DAOs. Due to how Hibernate manages certain relationships, some business logic operations need the DAOs. I will illustrate this use case below.

    My question is: How common is it to have Business Objects that contain DAOs? In the previous thread, we acknowledged that business objects, in order to perform business logic, need dependency injection. Here I ask: should we give DAOs to Business Objects?

    Use Case:

    A car detail shop needs to upgrade the wheels on a car. The old wheels are thrown away, and the new wheels are installed.

    Business Objects:

    Car, 1:Many Wheel
    DetailShop

    Methods:

    Code:
    DetailShop.upgradeWheels(Car, Wheel[] newWheels)
    or
    Code:
    Car.upgrade(Wheel[] wheels)
    Because Hibernate will not delete objects out of persistence if an object has its reference removed, we need to managed the deletion of old objects out of persistence manually.

    Car.upgrade() will look like this:

    Code:
    public void upgrade(Wheel[] newWheels) {
        Wheel[] oldWheels = getWheels();
        for (int i = 0; i < oldWheels.length; i++) {
            wheelDAO.delete(oldWheels[i]);
        }
        setWheels(newWheels);
    }
    If we were to just call
    Code:
    setWheels(newWheels)
    , the old wheels would never get deleted from the database.

    This also seems like it breaks encapsulation, since now these methods need to know the persistence details, but this is besides the point.

    What do others think? Does this approach make sense? Should Business Objects require DAOs to function? Obviously, someone needs to call dao.delete().

    As always, your thoughts and opinions are much appreciated!
    Seth
    Last edited by Rod Johnson; Jan 18th, 2006, 10:19 AM.

  • #2
    Seth,

    My currrent thinking here is that the domain objects should not have a reference to the dao layer. If they need help to instantiate or remove other domain objects then I would give them a helper class that could talk to the dao layer and do the work. This would keep the domain object layer isolated. If you evere switched the persistence model you might have to modify the interactions with the dao layer which would be part of the helper class rather than the domain layer. The domain layer would stay untouched. This is if you are trying to stick to a "transparent" persistence model. Actually, if we had a perfect transaparent persistence technology, then we would not need these helper classes. You would just remove the old tires and add the new ones.

    I would model the typical app using the following layers (leaving out the ui related stuff):

    1. domain objects - "transparently" persisted. These objects have behavior and interact with other domain objects. Any services needed are supplied via helper classes in utils layer.

    2. service layer - this layer acts as the gateway to the business logic and performs operations/transactions that involve complex interactions between domain objects like transaferring funds between accounts etc. Talks to the dao layer and the utils layer as well as the domain object layer.

    3. utils layer - helper classes providing integration services for domain objects and the service layer

    4. dao layer - this is the interface to the persistence layer used by the utils and service layers

    Comment


    • #3
      Thanks for the helpful reply. I agree that I don't really want to put the custom delete/remove logic directly inside my Business Object, as this greatly breaks encapsulation.

      Your suggestion of a DAO Util object is interesting, and makes sense. Am I correct in saying that the Business Object would have a reference to this Util object, thus delegating the custom persistence logic? Another example of a Spring managed Hibernate bean.

      If we take this one step further, and we do agree that Spring is managing Hibernate beans, then we can use Spring's AOP for this type of operation. Spring can apply the custom persistence aspect that will do the annoying, but necessary, persistence cleanup. This way, no Util object is needed.

      Your thoughts?

      Thanks!

      Comment


      • #4
        Seth,

        AOP is definitely an interesting option for the persistence work that some domain objects need to have done. I'm not sure that I would say that Spring manages the Hibernate beans, but your application is in control and will have to instruct Hibernate, or any other persistence mechanism, what to do at certain points. Much is taken care of by Spring, but there are a few things that need to be done either via AOP or a helper class.

        If you use a helper class, then the issue is, like you point out, how does the domain object get a reference to this helper class. IoC? Well Spring is not managing the creation - Hibernate is. AOP? Maybe, never tried that. Singleton? I'm not against calling a static getInstance method on the Helper class to get a reference. That way the domain object does not even have to hold on to the reference - just call Helper.getInstance().doSomething();

        Comment


        • #5
          I'm not sure that I would say that Spring manages the Hibernate beans
          I'm specifically talking about Spring creating prototypes on behalf of Hibernate, so that it may inject dependencies, or wrap the bean in an AOP proxy.

          Well Spring is not managing the creation - Hibernate is. AOP?
          I can definitely make Spring manage the creation instead of Hibernate. At this point, I can have Spring AOP the bean for me.

          This certainly is one possibility. My original discussion point was, what do other people do to manage this problem? Using a Singleton Util class, or a AOP proxy are two good solutions. I suspect that others are doing this work in the Service or Facade layer. To me, this smacks of duplicate work and work spread too far. It's certainly hard to avoid the persistence work when trying to do regular business logic, when our persistence frameworks aren't totally transparent.

          Comment


          • #6
            Seth,

            I can definitely make Spring manage the creation instead of Hibernate. At this point, I can have Spring AOP the bean for me.
            I just read the other threads related to this issue and now I do understand your point. Either way I'd prefer to have the dao related work encapsulated in a helper class keeping the business or domain objects pure.

            Comment


            • #7
              Originally posted by trisberg
              Either way I'd prefer to have the dao related work encapsulated in a helper class keeping the business or domain objects pure.
              Ditto here, for what it's worth.
              Scott

              Comment


              • #8
                Addressing your specific example, it seems that if the DAO is supposed to handle data access that a solution would be for the DAO to implement a mechanism whereby it could detect that old wheels were thrown away and so delete them automagically. You simply replace the wheels and update the car. The DAO will take care of deleting the old wheels. In fact, I believe Hibernate itself has such functionality available in the form of cascade="all-delete-orphan". In this case, if Hibernate detects that an element has been removed from a collection it will delete the element from the DB.

                Comment


                • #9
                  In fact, I believe Hibernate itself has such functionality available in the form of cascade="all-delete-orphan". In this case, if Hibernate detects that an element has been removed from a collection it will delete the element from the DB.
                  That is try, but there is no such help for a many-to-one relationship. Replacing the object still leaves the old object in the database. It's this explicit use case that requires my business object (or some DAO Util or some AOP wrapper) to manage this deletion.

                  If I could elegently solve this problem, Hibernate's persistence would truly be transparent!

                  Comment


                  • #10
                    I just read the other threads related to this issue and now I do understand your point. Either way I'd prefer to have the dao related work encapsulated in a helper class keeping the business or domain objects pure.
                    I agree, but the question is, where?

                    If I put this work in a DAO Util, my business object still needs a reference to this object. OK, not a big deal.

                    I could make a AOP proxy for this work, which is very transparent. I like this solution a lot.

                    I could put this logic in a Service type object, but then I see this as duplicate work just to keep business object pure. Every call to manipulate the business object would go through a Service layer, which sounds like bloat.

                    If Hibernate only had garbage collection.

                    Comment

                    Working...
                    X