Announcement Announcement Module
No announcement yet.
Hibernate lazy loading breaks DataAcessExceptions Page Title Module
Move Remove Collapse
Conversation Detail Module
  • Filter
  • Time
  • Show
Clear All
new posts

  • 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!

    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
    Are you using this in a web app? See the sionInViewFilter. Adding this into your app should solve your problems.


    • #3
      Originally posted by lightc
      Are you using this in a web app? See the 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
        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...


        • #5
          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.