Announcement Announcement Module
Collapse
No announcement yet.
Rich Domain Classes and Transactions Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Rich Domain Classes and Transactions

    Greetings,

    Let's say we have a layered system - domain, DAL, BL and web (the web controllers never access the DAOs directly). The DAOs are injected into the domain classes (using Spring's @Configurable) so for example when we want to persist a domain object we call its persist() method and internally the DAO's persist() method is called.
    But what about transaction management? In the layered system only the BL layer is marked with @Transactional, so if we were to call the object's persist() method from a controller - it would happen outside a transaction, so the options I see are:

    1. Make the web controllers @Transactional - bad design - its not this layer's real role

    2. Make the domain or DAO classes @Transactional - bad design and not necessarily correct (for example I may want to persist several objects in one transaction)

    3. Send the object to a BL layer and there its persist() method will be called - sounds like the cleanest solution, but then my domain classes persist() method remains exposed for the web-tier developers when they are not supposed to use it directly, and the object is sent to a BL method in a "non-OO" way, so I might as well drop the persist() method from the domain class and send the domain object from the BL to the DAO directly.

    What do you think the best solution is? I there a better option I didn't consider?

    Thanks,

    Gabriel

  • #2
    There is discussion going on on the fact if an object should persist itself or not. I'm one of the believers that it should not. Retrieving it is also done through a service which calls a repository. So I wouldn't even have/implement a persist but make a service with a persist/store method. That way your boundaries (transactional/security) are all in one place.

    Comment


    • #3
      Personally I prefer some kind of business layer that takes care of these issues:

      Code:
      class EmployeeService{
          @transactional
          void fire(long id){
               Employee e = employeeDao.load(id);
               e.fire();
         }
      }
      If you want to have a rich domain model, you can add the logic to the fire method of the employee, or create some kind of fire domain service (domain service is not the same as an application service.. see DDD for more information).

      Code:
      class EmployeeService{  // is application service 
          @transactional
          void fire(long id){
               Employee e = employeeDao.load(id);
               fireService.fire(e);   //fire service is domain service
         }
      }
      When you are using some kind of session based or technology (like Hibernate) you don't have to call save/update (I really hate these names). You have to make sure that your objects are attached to the session, after that you don't need to worry about save/update anymore.
      Last edited by Alarmnummer; Feb 15th, 2008, 04:44 AM.

      Comment


      • #4
        If you really want to bypass your business layer, I think 2 is not such a bad design decision. If you have multiple domain objects you want to persist in the same transaction, just create some @Transactional method in your BL that wraps these operations. The @Transaction persist methods will join this transaction

        /Magnus

        Comment

        Working...
        X