Announcement Announcement Module
Collapse
No announcement yet.
Throw own exceptions using Hibernate & Spring Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Throw own exceptions using Hibernate & Spring

    I am a newbie to Spring, and to Hibernate, but enjoying the combination of both at the moment!

    I have set up my DAOs to extend HibernateDaoSupport, and my methods use getHibernateTemplate() eg

    return getHibernateTemplate().find("from Category");

    However, I would like to implement my own exception hierarchy, and throw my own exceptions instead of the Spring/Hibernate ones.

    Is there an easy way to do this (eg some Spring wizardry!), rather than putting a try-catch block in all my methods?

    cheers,

    David

  • #2
    hhhmm, you asked for some "Spring wizardry!", here you are:

    I think this is an excellent case for some AOP magics. I will define an interceptor for all the DAO (or services if you like) calls. My interceptor will intercept :wink: Spring unchecked exceptions (all Spring thrown exceptions are unchecked), extract the cause exception and convert it to a User Defined Exception.

    1. my interceptor
    Code:
    import org.aopalliance.intercept.MethodInterceptor;
    import org.aopalliance.intercept.MethodInvocation;
    import org.springframework.core.NestedRuntimeException;
    
    public class Interceptor implements MethodInterceptor {
      public Object invoke(MethodInvocation invocation) throws Throwable {
        try {
          //invoke the underlying method
          Object result = invocation.proceed();
          return result;
        } catch (NestedRuntimeException e) {
          //extract the cause exception
          NestedRuntimeException cause = e.getCause();
          //convert the exception into User defined exception then rethrow it
          throw new Exception ("error returned", e.getCause());
        }
      }
    }
    2. configure my interceptor in applicationContext.xml
    Code:
      <bean id="myInterceptor"  class="Interceptor" />
    3. configure a transaction template, I will omit the configuration for transactionManager and sessionFactory:
    Code:
      <!-- transaction template -->
      <bean id="txProxyTemplate" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean" lazy-init="true">
        <property name="transactionManager"><ref local="transactionManager"/></property>
        <property name"preInterceptors">
          <list>
            <ref local="myInterceptor"/>
          </list>
        </property>
        <property name="transactionAttributes">
          <props>
            <prop key="get*">PROPAGATION_REQUIRED,readOnly</prop>
            <prop key="save*">PROPAGATION_REQUIRED</prop>
            <prop key="delete*">PROPAGATION_REQUIRED</prop>
          </props>
        </property>
      </bean>
    This is one way to do it, thank you Colin!!!
    4. configure myDAO (no changes required!!!)
    Code:
      <bean id="myDAO" parent="txProxyTemplate">
        <property name="target">
          <bean class="MyDAO">
            <property name="sessionFactory"><ref local="sessionFactory"/></property>
          </bean>
        </property>
      </bean>

    Comment


    • #3
      Very cool Omar. What if you're using CMT and so therefore you don't have your section 3 in your applicationContext.xml? Do you just directly add your Inteceptor as a parent to the DAOs? Or could you do this:

      Code:
      	<bean id="clmDaoTarget" singleton="false" 
      		class="com.mitchell.services.technical.claim.dao.spring.ClmActivityLogHibernateDao">
      		<property name="sessionFactory">
      			<ref local="mySessionFactory"/>
      		</property>
      	</bean>
      	<bean id="clmActivityLogDao" 
      		class="org.springframework.aop.framework.ProxyFactoryBean">
      		<property name="proxyInterfaces">
      			<value>com.mitchell.services.technical.claim.dao.ClmActivityLogDao</value>
      		</property>
      		<property name="interceptorNames">
      			<list>
      				<value>myHibernateInterceptor</value>
      				<value>clmActivityLogDaoTarget</value>
      				<value>myInterceptor</value>  <<<<<<<<
      			</list>
      		</property>
      	</bean>
      Thanks,
      Lou

      Comment


      • #4
        <bean id="clmDaoTarget" singleton="false" class="com.mitchell.services.technical.claim.dao.s pring.ClmActivityLogHibernateDao">
        <property name="sessionFactory">
        <ref local="mySessionFactory"/>
        </property>
        </bean>
        <bean id="clmActivityLogDao" class="org.springframework.aop.framework.ProxyFact oryBean">
        <property name="proxyInterfaces">
        <value>com.mitchell.services.technical.claim.dao.C lmActivityLogDao</value>
        </property>
        <property name="interceptorNames">
        <list>
        <value>myHibernateInterceptor</value>
        <value>clmActivityLogDaoTarget</value>
        <value>myInterceptor</value> <<<<<<<<
        </list>
        </property>
        </bean>
        Well, you have to change a bit the order of your interceptors
        Code:
          <bean id="clmDaoTarget" singleton="false" class="com.mitchell.services.technical.claim.dao.spring.ClmActivityLogHibernateDao"> 
            <property name="sessionFactory"> 
              <ref local="mySessionFactory"/> 
            </property> 
          </bean> 
          <bean id="clmActivityLogDao" class="org.springframework.aop.framework.ProxyFactoryBean"> 
            <property name="proxyInterfaces"> 
              <value>com.mitchell.services.technical.claim.dao.ClmActivityLogDao</value> 
            </property> 
            <property name="interceptorNames"> 
              <list> 
                <value>myInterceptor</value>
                <value>myHibernateInterceptor</value> 
                <value>clmActivityLogDaoTarget</value> 
              </list> 
            </property> 
          </bean>
        the target bean (clmActivityLogDaoTarget) must always be the last object in your call stack. myInterceptor should be called first because it has to catch all the thrown exceptions.

        Comment


        • #5
          Best practise

          Hi
          I'm just curious, could you guys say something about best practises here? I'm a newbie, and I'm used to creating my own exception hierarchy, but none of the examples with HibernateDAOSupport I've seen do this. And I remember reading somewhere that not having to catch the exceptions when extending HibernateDAOSupport was a good thing.. Is this just a matter of taste?

          - Kristian

          Comment


          • #6
            You are right kristian. I think that Spring complicated the problem a little bit too much.

            Comment


            • #7
              I don't think it's that complicated. Spring provides a nice hierarchy of exceptions, why would you want to replace this with your own?
              http://www.springframework.org/docs/...dao-exceptions

              Comment

              Working...
              X