Results 1 to 5 of 5

Thread: Hibernate lazy loading breaks DataAcessExceptions

  1. #1
    Join Date
    Jun 2005
    Posts
    10

    Default Hibernate lazy loading breaks DataAcessExceptions

    Let's consider the following architecture:

    Services use DAOs to manipulate Domain Objects. Services make all efforts to be really isolated (and agnostic) from data access technology.

    But, when DAOs are specifically Hibernate DAOs, lazy loading proxies get into the way, so any HibernateException occurred during lazy loading will not be translated, and will leak into Service classes :!: (see code below)

    I am having big trouble trying to make DAOs and Services really reusable and properly isolated. OK, I could install interceptors here and there to translate leaked HibernateExceptions back into DataAccessExceptions... But I think it begins to get messy... :roll:

    So I'm asking your help, thanks in advance!

    Code:
    public interface CustomerService
    {
        Customer login(String id, String password) throws LoginException;
    }
    
    public class CustomerServiceImpl implements CustomerService
    {
        private CustomerDAO customerDAO;
    
        public setCustomerDAO(CustomerDAO customerDAO)
        {
            this.customerDAO = customerDAO;
        }
    
        public Customer login(String id, String password) throws LoginException
        {
            Customer customer = customerDAO.findById(id);
    
            // verify password and throw LoginException on failure
    
            // but hey, a database failure on loading any lazy 
            // loaded Customer property (not only collections, but any 
            // Hibernate3 lazy loaded instance) will result on HibernateException,
            // thus leaking technology specific Exceptions into Service Layer
            // and also breaking DataAccessException philosophy...!
    
            return customer;
        }
    }
    
    public interface CustomerDAO
    {
        Customer findById(String id) throws DataAccessException;
    }
    
    public class CustomerDaoImpl extends HibernateDaoSupport implements CustomerDAO
    {
        public Customer findById(String id) throws DataAccessException    
        {
            return (Customer)getHibernateTemplate().load(Customer.class, id);        
        }
    }

  2. #2
    Join Date
    Jun 2005
    Posts
    19

    Default

    Are you using this in a web app? See the org.springframework.orm.hibernate3.support.OpenSes sionInViewFilter. Adding this into your app should solve your problems.

  3. #3
    Join Date
    Jun 2005
    Posts
    10

    Default

    Quote Originally Posted by lightc
    Are you using this in a web app? See the org.springframework.orm.hibernate3.support.OpenSes sionInViewFilter. Adding this into your app should solve your problems.
    I am already using OpenSessionInViewFilter, lightc. The problem is not the absence of a Session, but the HibernateExceptions which may be thrown by Hibernate proxies.

    Let's supposed that some method in service layer uses a DAO to retrieve any entity. Hibernate will provide a proxied entity. So, if you try to access any property which is lazy loaded by the proxy, a HibernateException may occur.

    So, if you're trying to isolate tiers, suddenly a HibernateException will occur outside the DAO (in service layer, in this case). So the service layer should now be aware of Hibernate, and tier isolation blows away. Spring's DataAccessException philosophy blows away too.

    I am trying to figure out what should be done to avoid this. Maybe to write some kinda wrapper around the service layer?

  4. #4
    Join Date
    Aug 2004
    Location
    San Mateo, CA
    Posts
    1,265

    Default

    Yes, this is definitely a danger of lazy loading. It does break the Spring exception contract. However, I think the real question is how you would handle the error, regardless of the exception. If you don't have the data, the page will presumably break or be misleading to the user, and exactly which exception you're dealing with is more a cosmetic issue.

    So I would advice ensuring that your application is tested so that a lazy loading error cannot occur. (Or perhaps use Open Session in View, although I'm not a great fan of that approach.)

    The org.springframework.test package enables you to test your code outside the web container but hitting a real database. There is an endTransaction() method that enables you to end the transaction and then touch relationships as you like, to ensure that adequate data has been loaded. Much faster to find problems and prevent regressions that relying on navigating through your pages by hand...
    Rod Johnson - GM, SpringSource Division, VMware
    http://www.springsource.com
    Spring From the Source

  5. #5
    Join Date
    Jun 2005
    Posts
    10

    Default

    Quote Originally Posted by Rod Johnson
    Yes, this is definitely a danger of lazy loading....
    Thank you, Rod!

    Since I'm new to both Spring and Hibernate, I was afraid I could be missing important detail and misinterpreting something. Sometimes I think that trying to achieve perfect tier isolation and a high level of technology 'independence' can make things worse in some cases.

    I was thinking "Hmmm, I shouldn't have HibernateExceptions outside my DAOs, at least the DAOs should catch them and rethrow them as generic DAOExceptions".

    But, after reading your reply, I can see that I must reconsider about it.

Similar Threads

  1. Hibernate Long Session Per Flow?
    By akw in forum Web Flow
    Replies: 21
    Last Post: Dec 12th, 2005, 08:06 PM
  2. Replies: 2
    Last Post: Dec 8th, 2005, 09:00 AM
  3. how to use hibernate lazy loading with spring transaction
    By tanmoy.chakraborty in forum Data
    Replies: 1
    Last Post: Oct 11th, 2005, 02:07 AM
  4. Hibernate and Lazy Loading.
    By cmrudd in forum Data
    Replies: 1
    Last Post: Oct 3rd, 2005, 03:58 AM
  5. Lazy loading + Hibernate
    By benef in forum Data
    Replies: 2
    Last Post: Mar 18th, 2005, 01:17 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
  •