View Full Version : Throw own exceptions using Hibernate & Spring
hay7777
Aug 16th, 2004, 05:19 PM
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
irbouho
Aug 16th, 2004, 07:14 PM
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
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
<bean id="myInterceptor" class="Interceptor" />
3. configure a transaction template, I will omit the configuration for transactionManager and sessionFactory:
<!-- transaction template -->
<bean id="txProxyTemplate" class="org.springframework.transaction.interceptor.Transa ctionProxyFactoryBean" 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 (http://blog.exis.com/colin/archives/2004/07/31/concise-transaction-definitions-spring-11/)!!!
4. configure myDAO (no changes required!!!)
<bean id="myDAO" parent="txProxyTemplate">
<property name="target">
<bean class="MyDAO">
<property name="sessionFactory"><ref local="sessionFactory"/></property>
</bean>
</property>
</bean>
Loumeister
Aug 17th, 2004, 05:52 PM
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:
<bean id="clmDaoTarget" singleton="false"
class="com.mitchell.services.technical.claim.dao.spring.C lmActivityLogHibernateDao">
<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.ClmActiv ityLogDao</value>
</property>
<property name="interceptorNames">
<list>
<value>myHibernateInterceptor</value>
<value>clmActivityLogDaoTarget</value>
<value>myInterceptor</value> <<<<<<<<
</list>
</property>
</bean>
Thanks,
Lou
irbouho
Aug 17th, 2004, 08:10 PM
<bean id="clmDaoTarget" singleton="false" class="com.mitchell.services.technical.claim.dao.spring.C lmActivityLogHibernateDao">
<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.ClmActiv ityLogDao</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 ;)
<bean id="clmDaoTarget" singleton="false" class="com.mitchell.services.technical.claim.dao.spring.C lmActivityLogHibernateDao">
<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.ClmActiv ityLogDao</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.
kristian
Sep 4th, 2004, 02:53 PM
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
geodad
Oct 10th, 2007, 03:36 AM
You are right kristian. I think that Spring complicated the problem a little bit too much.:confused:
karldmoore
Oct 11th, 2007, 02:19 PM
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/reference/dao.html#dao-exceptions
Powered by vBulletin® Version 4.2.1 Copyright © 2013 vBulletin Solutions, Inc. All rights reserved.