|
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
|
|
|---|---|
| 作者 | 正文 |
|
最后更新时间:2006-01-19
现在项目中用到了spring+hibernate的框架。但有关其中的异常处理还有点不明白。
现在的框架是这样: WEB <-> Service <-> DAO <-> Database DAO是继承HibernateDaoSupport。 [code:1]public class UserDaoImpl extends HibernateDaoSupport implements UserDao { public User addUser(User user) throws DataAccessException { this.getHibernateTemplate().save(user); Hibernate.initialize(user); return user; } ... }[/code:1] Service层是业务方法,调用DAO的功能: [code:1]public class UserServiceImpl implements UserService { private UserDao userDao; public void setUserDao(UserDao userDao) { this.userDao = userDao; } public User addUser(User user) { return userDao.addUser(user); } ... }[/code:1] Web层采用struts,action中直接调用service的各种方法。 service中的事务采用了声明式事物: [code:1] <bean id="userServiceTarget" class="com.javaeye.service.impl.UserServiceImpl"> <property name="userDao"><ref local="userDao"/></property> </bean> <bean id="userService" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean"> <property name="transactionManager"><ref local="transactionManager"/></property> <property name="target"><ref local="userServiceTarget"/></property> <property name="transactionAttributes"> <props> <prop key="get*">PROPAGATION_REQUIRED,readOnly</prop> <prop key="add*">PROPAGATION_REQUIRED</prop> <prop key="update*">PROPAGATION_REQUIRED</prop> <prop key="delete*">PROPAGATION_REQUIRED</prop> </props> </property> </bean>[/code:1] 以上是大概的架构。现在的问题是如何将spring抛出的异常转换成自己的异常。在DAO中,各种调用HibernateTemplate的方法好像都抛出DataAccessException,但我在DAO中的代码,好像不能直接catch这个异常: [code:1]try { this.getHibernateTemplate().save(user); Hibernate.initialize(user); return user; } catch (DataAccessException ex) { ... }[/code:1] 好像不会跳到异常处。 只能让DAO将异常往上抛给service,service也没法直接catch,直接抛给要调用service的action,action中catch DataAccessException,然后转换成自己的Exception。 不知道各位是怎么处理spring中的异常的? 声明:JavaEye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
|
|
| 返回顶楼 | |
|
最后更新时间:2006-01-16
Spring不是已经帮你把所有的异常都转化成DataAccessException了嘛,你还包装啥呢?
|
|
| 返回顶楼 | |
|
最后更新时间:2006-01-16
//先自定义一个异常
[code:1]public class FooException extends DataAccessException{ public FooException(String msg){ this.msg = msg; } //..... }[/code:1] 在struts-config.xml声明一下 [code:1] <global-exceptions> <exception key="global.data.access.exception" path="/pages/error.jsp" scope="request" type="yourpackage.FooException "/> </global-exceptions>[/code:1] 事务: [code:1] <bean id="userService" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean"> <property name="transactionManager"><ref local="transactionManager"/></property> <property name="target"><ref local="userServiceTarget"/></property> <property name="transactionAttributes"> <props> <prop key="get*">PROPAGATION_REQUIRED,readOnly,-FooException</prop> <prop key="add*">PROPAGATION_REQUIRED,-FooException</prop> <prop key="update*">PROPAGATION_REQUIRED,-FooException</prop> <prop key="delete*">PROPAGATION_REQUIRED,-FooException</prop> </props> </property> </bean>[/code:1] 捕获: [code:1]try { User user = (User)this.getHibernateTemplate().load(User.class, userId); } catch (FooException ex) { ... }[/code:1] |
|
| 返回顶楼 | |
|
最后更新时间:2006-01-16
我按照你的方法,不管是DAO还是service,还是不能执行到catch里面的代码。
|
|
| 返回顶楼 | |
|
最后更新时间:2006-01-16
AndyTse 写道 我按照你的方法,不管是DAO还是service,还是不能执行到catch里面的代码。
[code:1]try { User user = (User)this.getHibernateTemplate().load(User.class, userId); } catch (Exception ex) { throws new FooException(ex.getMessage()); }[/code:1] 首先你要确定你抛出的什么类型的异常?DataAccessException是RuntimeException, 属于uncheck异常! 如果你程序抛的是VirtualMacthineError或SQLException,IOException是check异常当然捕获不到。建议你设个断点看看出错的代码抛出的什么类型的异常再用相应的异常catch.... |
|
| 返回顶楼 | |
|
最后更新时间:2006-01-17
我在做testcase,故意insert两条主键一样的记录,报的错是:
hibernateTest.UserTest)org.springframework.dao.DataIntegrityViolationException: 在代码中捕获的是DataAccessException,但没有作用。 |
|
| 返回顶楼 | |
|
最后更新时间:2006-01-17
AndyTse 写道 我在做testcase,故意insert两条主键一样的记录,报的错是:
hibernateTest.UserTest)org.springframework.dao.DataIntegrityViolationException: 在代码中捕获的是DataAccessException,但没有作用。 java.lang.Object |_java.lang.Throwable  |_ java.lang.Exception    |_ java.lang.RuntimeException     |_ org.springframework.core.NestedRuntimeException      |_ org.springframework.dao.DataAccessException       |_ org.springframework.dao.DataIntegrityViolationException   DataIntegrityViolationException是继承DataAccessException。看看spring源码里的HibernateTemplate类,它把DataAccessException异常都往上层调用者throws. 引用 注意看注释:checked HibernateExceptions into unchecked DataAccessException
所以DataAccessException应该在service层中被catch。重现了你的重复主键test,是可以捕获的,只需你的DaoImpl类中这样改一下,在serviceImpl调用这个DAO处catch就可以了!: [code:1]public void insertObject(//....) throws DataAccessException{ }[/code:1] 我的测试环境是:spring2.0 + hibernate3.1+ mysql5.1 |
|
| 返回顶楼 | |
|
最后更新时间:2006-01-17
我试了下还是无效啊,我把我代码贴出来:
applicationContext.xml: [code:1] <!-- User Service Definition --> <bean id="userServiceTarget" class="com.javaeye.service.impl.UserServiceImpl"> <property name="userDao"><ref local="userDao"/></property> </bean> <!-- Transactional proxy for the User Service --> <bean id="userService" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean"> <property name="transactionManager"><ref local="transactionManager"/></property> <property name="target"><ref local="userServiceTarget"/></property> <property name="transactionAttributes"> <props> <prop key="get*">PROPAGATION_REQUIRED,readOnly</prop> <prop key="add*">PROPAGATION_REQUIRED</prop> <prop key="update*">PROPAGATION_REQUIRED</prop> <prop key="delete*">PROPAGATION_REQUIRED</prop> </props> </property> </bean>[/code:1] UserDaoImpl.java: [code:1]public class UserDaoImpl extends HibernateDaoSupport implements UserDao { public User addUser(User user) throws DataAccessException { this.getHibernateTemplate().save(user); Hibernate.initialize(user); return user; } }[/code:1] UserServiceImpl.java: [code:1] public User addUser(User user) { try { userDao.addUser(user); return user; } catch (DataAccessException ex) { System.out.println("error.."); return null; } }[/code:1] UserTest.java: [code:1] public void testCreateUser() { User user = new User(); user.setUserId(newUserId); User newUser = userService.addUser(user); if (newUser != null) { assertEquals(newUser.getUserId(), newUserId); } }[/code:1] 测试结果是: testCreateUser(hibernateTest.UserTest)org.springframework.dao.DataIntegrityViolationException: Hibernate operation: Could not execute JDBC batch update; SQL [insert into USER (NAME, PASSWORD, EMAIL, EXPIRED_MONTH, LOCK_TIME, LEVEL_ID, DEPT_ID, USER_ID) values (?, ?, ?, ?, ?, ?, ?, ?)]; Duplicate entry 'admin' for key 1; nested exception is java.sql.BatchUpdateException: Duplicate entry 'admin' for key 1 java.sql.BatchUpdateException: Duplicate entry 'admin' for key 1 ... 我的环境是spring1.2.6 + Hibernate3 + mysql4.0. 换成spring2也一样。 |
|
| 返回顶楼 | |
|
最后更新时间:2006-01-17
但如果捕获DataAccesException的代码放到testCreateUser里面,是可以的。
[code:1] try { User newUser = userService.addUser(user); if (newUser != null) { assertEquals(newUser.getUserId(), newUserId); } } catch (DataAccessException ex) { System.out.println("failure"); //主键出错时候,会执行的到。 }[/code:1] |
|
| 返回顶楼 | |
|
最后更新时间:2006-01-18
AndyTse 写道 我在做testcase,故意insert两条主键一样的记录,报的错是:
hibernateTest.UserTest)org.springframework.dao.DataIntegrityViolationException: 在代码中捕获的是DataAccessException,但没有作用。 在可能出错的地方增加getTemplate.getSession().flush() |
|
| 返回顶楼 | |







