Announcement Announcement Module
Collapse
No announcement yet.
Spring+Hibernate in a layered architecture Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Spring+Hibernate in a layered architecture

    Hi,

    I use Hibernate and I'm having trouble with persistent objects and transactions.

    In my business layer I call my DAO methods (e.g. load) that in turn call HibernateTemplate.load and return the persisted object to the business layer.
    There I want use it as it were a Transfer Object, changing some of its values, but as it's done inside a transaction the object is cached in the session and every change I made to it is persisted when closing the session at the end of the transaction (are these assumptions true?)
    Seems that there's no method to dettach persisted objects from the session and maybe a solution could be return a clone of the persisted object in the DAO or creating a Transfer Object with data from the persisted object.

    If anyone asks about it I don't want to use the OpenSessionInView filter as it breaks the layered architecture.

    And a sample can be a use case where I want to return a department with only the employees that have some attribute. I load the department object with a lazy collection of employees calling dao.load(). Then I can call dao.getEmployeesXXX that uses a filter to get only a subset of employees from the lazy collection).
    To sum up:
    Code:
    department = dao.load(id);
    department.setEmployees(dao.getEmployeesXXX(department));
    if department is the same object as returned by Hibernate then I'll get errors or it will be update in database with only those employees from dao.getEmployeesXXX

    Thanks in advance.

  • #2
    With Hibernate3 you could use Filters :wink:

    I think you can do the following:
    Code:
      //add a copy contructor to your Department class
      public Department(Department department) {
        //copy base properties
      }
    
      //then in your DAO
      department = dao.load(id); 
      Department dept = new Department(department );
      dept.setEmployees(dao.getEmployeesXXX(department));
    If you do not like the copy constructor (as in normal use, it should also copy the employees), you can copy a subset properties with d1.setXXX(d2.getXXX()) in your dao.

    Comment


    • #3
      Yes I have read something about Hibernate3, but I can't wait :cry:

      The copy constructor is almost the same option as cloning, I think that's what I'll use if there's no better option, but a better approach than your implementation can be using commons-beanutils reflection methods.

      I think somebody else has to have faced this problem because one of the main reasons to use ORM is not to code TOs

      Comment


      • #4
        Hi Carlos,

        Let me make sure about your question and then I'll give it a shot. You want to load an object (I'll use your Department/Employees examples), filter it's collections and then return it to your view. You are concerned that by filtering the collection the Employees removed by the filter will lose their association to the Department when the session is flushed (ie when the transaction commits).

        If this is the case you want to mark your transaction as readOnly. When using hibernate this means the session will not be flushed. There was just recently a thread on this here,

        http://forum.springframework.org/showthread.php?t=9675

        Hope this is helpful,

        Mike
        Last edited by Rod Johnson; Jan 18th, 2006, 11:10 AM.

        Comment


        • #5
          but a better approach than your implementation can be using commons-beanutils reflection methods.
          Agree, however I think making my domain object dependent on commons-beanutils would not be a good design.

          Comment


          • #6
            Originally posted by futang
            You are concerned that by filtering the collection the Employees removed by the filter will lose their association to the Department when the session is flushed (ie when the transaction commits).
            You're right

            Originally posted by futang
            If this is the case you want to mark your transaction as readOnly.
            This is not possible some times, e.g. I want the createDepartment method to return the created object, so in that transaction I want to both update database and transform an hibernate persisted object in a TO.

            Comment


            • #7
              Would a session.evict(Object) accomplish what you want? It detaches the instance from the currently open session.
              -wd

              Comment


              • #8
                But also prevents flushing wanted changes to database

                Comment

                Working...
                X