Announcement Announcement Module
Collapse
No announcement yet.
Best practices for handling exceptions (Hibernate/Struts)? Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Best practices for handling exceptions (Hibernate/Struts)?

    Hi

    I've build my application with Spring and I was wondering how people solve the RuntimeExceptions from f.e. Hibernate integration in the Web Layer?

    Do you provide exception handling on the Service layer, so that the Struts layer can provide clean error messages to the user?
    Do you define an exception class in the Action declaration in struts-config.xml?
    Do you define exception pages in web.xml?

    Other solutions/preferences?

  • #2
    Hi Gunther,

    One feature Spring touts at the data layer is unified exception handling. From the HibernateTemplate in the Spring javadoc:

    '[HibernateTemplate is a ]Helper class that simplifies Hibernate data access code, and converts checked HibernateExceptions into unchecked DataAccessExceptions, following the org.springframework.dao exception hierarchy. Uses the same SQLExceptionTranslator mechanism as JdbcTemplate.'

    I have Spring configured for Hibernate like so:
    Code:
          <!-- These are equivalent entries from the the hibernate.cfg.xml properties -->
          <property name="hibernateProperties">
            <props>
              <prop key="hibernate.dialect">net.sf.hibernate.dialect.PostgreSQLDialect</prop>
              <prop key="hibernate.show_sql">false</prop>
              <prop key="hibernate.cache.provider_class">net.sf.hibernate.cache.EhCacheProvider</prop>
              <prop key="hibernate.jdbc.batch_size">5</prop>
              <prop key="hibernate.cache.max_fetch_depth">3</prop>
            </props>
          </property>
          <property name="dataSource">
            <ref bean="MyDataSource"/>
          </property>
        </bean>
    
        <!-- Transaction manager for the HibernateSessionFactory (alternative to JTA) -->
        <bean id="appTransactionManager" class="org.springframework.orm.hibernate.HibernateTransactionManager">
          <property name="sessionFactory">
            <ref local="appSessionFactory"/>
          </property>
        </bean>
    
        <!-- The Hibernate iterceptor provides support for Hibernate Session and Transaction objects -->
        <bean id="appHibernateInterceptor" class="org.springframework.orm.hibernate.HibernateInterceptor">
          <property name="sessionFactory">
            <ref bean="appSessionFactory"/>
          </property>
        </bean>
    Each of my DAO objects looks similar to this:
    Code:
      <bean id="UserLoginDaoInteceptor" class="org.springframework.aop.framework.ProxyFactoryBean">
        <property name="proxyTargetClass"><value>true</value></property>
        <property name="interceptorNames">
          <value>appHibernateInterceptor,UserLoginDao</value>
        </property>
      </bean>
    
      <bean id="UserLoginDao" class="my.dao.UserLoginDao">
        <property name="sessionFactory">
          <ref bean="appSessionFactory"/>
        </property>
      </bean>
    My service is as follows:
    Code:
      <!-- Login service and interceptor -->
      <bean id="svcIntLoginTarget" class="my.service.LoginService">
        <property name="userLoginDao">
          <ref bean="UserLoginDao"/>
        </property>
        <property name="personDao">
          <ref bean="PersonDao"/>
        </property>
      </bean>
    
      <bean id="svcIntLogin" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
        <property name="transactionManager"><ref bean="appTransactionManager"/></property>
        <property name="target"><ref bean="svcIntLoginTarget"/></property>
        <property name="transactionAttributes">
          <props>
            <prop key="login">PROPAGATION_REQUIRED,readOnly</prop>
          </props>
        </property>
        <property name="proxyTargetClass" value="true"/>
      </bean>
    Now if you look at Spring's HibernateTemplate or HibernateDaoSupport, you'll see they throw a org.springframework.dao.DataAccessException. I can either catch this at the service level or have each of my service methods specify 'throws DataAccessException' and catch it at the controller. I don't think either of these two ways is right or wrong and I've seen it done both ways. I think the Service level is probably cleanest as I have mine catching the exception based on the business transaction being done and then returning a success or error code to the controller, which is then responsible for returning the proper i18n error message. This also allows the controller to focus more on providing validation that doesn't get jumbled up with business exceptions. Again, this is mostly preference.

    I hope this clears things up a little bit and if it doesn't, lemmie know what you think.

    - jason

    Comment

    Working...
    X