Spring中的异常处理

时间:2015-02-23 16:51:01

标签: java spring

我正在使用带有hibernate的spring,当我尝试插入已经存在的数据时,它会抛出DataIntegrityViolationException。 因此,为了处理这个异常,我在DAO层的save方法中放置了一个try / catch块,但它没有被捕获。 之后我在服务层的保存方法中放置了一个try / catch块,但也没有被捕获。

我的服务层中有一个testMain方法,当我在那里处理时,它会被抓到那里。

请帮助我在DAO图层中处理这个问题

public class TestMain {

    /**
     * @param args
     */
    public static void main(String[] args) {
        ApplicationContext applicationContext = SpringUtil
                .getApplicationContextInstance();
        UserDaoService userDaoService = applicationContext.getBean("userDaoService",
                UserDaoService.class);
        UserDaoImpl userDao = applicationContext.getBean("userDaoImpl",
                UserDaoImpl.class);

        User user = new User();
        user.setActive(true);
        user.setEmail("shariquealam01@gmail.com");
        user.setFirstName("Md");
        user.setMiddleName("Sharique");
        user.setLastName("Alam");
        user.setId(1);
        user.setPassword("123");
        user.setUserName("shariquealam01");
        userDaoService.saveUser(user);
    }
}

@服务

public class UserDaoService {
    @Autowired
    public UserDao userDao;

    @Transactional
    public void saveUser(User user){
        System.out.println("User Saving");  
        /*user.setActive(true);
        user.setEmail("shariquealam06@gmail.com");
        user.setFirstName("Md");
        user.setMiddleName("Sharique");
        user.setLastName("Alam");
        user.setId(6);
        user.setPassword("123");
        user.setUserName("shariquealam06");*/       
            userDao.saveUser(user) ;        
        /*try{
            System.out.println("Inside Service Try");
            userDao.saveUser(user);
        } catch (Exception e){
            System.out.println("Exception Occured "+e);
        }*/
            // deleteUser(3);
    }
}

@Repository
public class UserDaoImpl implements UserDao {   
    @Autowired
    private SessionFactory sessionFactory;


    public Role getRole(int id){
        Session session = getSessionFactory().getCurrentSession();
        Role role = (Role) session.get(Role.class, id);
        return role;
    }

    @Override
    public void saveUser(User user)  {
        //  Session session = getSessionFactory().getCurrentSession();
        /*role.setRoleId(102);
        role.setRoleName("User");*/     
        //  role.getUsers().add(user);
        /*session.save(user);*/

            //logger.info( "Executing Query to ADD User"); //Since this query is important for the state of application, have info logging

            Role role = getRole(102);
            user.getRoles().add(role);
            Session session = sessionFactory.getCurrentSession();
            session.save( user );
            //userId = user.getId();
            //logger.info( "User ADDED to DB with userId as {}", user.getId() );


        //session.save(role);
    }
}

Exception in thread "main" org.springframework.dao.DataIntegrityViolationException: could not execute statement; SQL [n/a]; constraint [null]; nested exception is org.hibernate.exception.ConstraintViolationException: could not execute statement
    at org.springframework.orm.hibernate4.SessionFactoryUtils.convertHibernateAccessException(SessionFactoryUtils.java:163)
    at org.springframework.orm.hibernate4.HibernateTransactionManager.convertHibernateAccessException(HibernateTransactionManager.java:730)
    at org.springframework.orm.hibernate4.HibernateTransactionManager.doCommit(HibernateTransactionManager.java:592)
    at org.springframework.transaction.support.AbstractPlatformTransactionManager.processCommit(AbstractPlatformTransactionManager.java:757)
    at org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:726)
    at org.springframework.transaction.interceptor.TransactionAspectSupport.commitTransactionAfterReturning(TransactionAspectSupport.java:515)
    at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:291)
    at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:96)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
    at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:653)
    at com.sharique.service.UserDaoService$$EnhancerBySpringCGLIB$$956522ab.saveUser(<generated>)
    at com.sharique.main.TestMain.main(TestMain.java:40)
Caused by: org.hibernate.exception.ConstraintViolationException: could not execute statement
    at org.hibernate.exception.internal.SQLStateConversionDelegate.convert(SQLStateConversionDelegate.java:129)
    at org.hibernate.exception.internal.StandardSQLExceptionConverter.convert(StandardSQLExceptionConverter.java:49)
    at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:126)
    at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:112)
    at org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.executeUpdate(ResultSetReturnImpl.java:211)
    at org.hibernate.engine.jdbc.batch.internal.NonBatchingBatch.addToBatch(NonBatchingBatch.java:62)
    at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:3124)
    at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:3581)
    at org.hibernate.action.internal.EntityInsertAction.execute(EntityInsertAction.java:104)
    at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:465)
    at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:351)
    at org.hibernate.event.internal.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:350)
    at org.hibernate.event.internal.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:56)
    at org.hibernate.internal.SessionImpl.flush(SessionImpl.java:1222)
    at org.hibernate.internal.SessionImpl.managedFlush(SessionImpl.java:425)
    at org.hibernate.engine.transaction.internal.jdbc.JdbcTransaction.beforeTransactionCommit(JdbcTransaction.java:101)
    at org.hibernate.engine.transaction.spi.AbstractTransactionImpl.commit(AbstractTransactionImpl.java:177)
    at org.springframework.orm.hibernate4.HibernateTransactionManager.doCommit(HibernateTransactionManager.java:584)
    ... 9 more
Caused by: com.microsoft.sqlserver.jdbc.SQLServerException: Violation of PRIMARY KEY constraint 'PK__USER_DET__F3BEEBFF77DFC722'. Cannot insert duplicate key in object 'dbo.USER_DETAILS'.
    at com.microsoft.sqlserver.jdbc.SQLServerException.makeFromDatabaseError(SQLServerException.java:216)
    at com.microsoft.sqlserver.jdbc.SQLServerStatement.getNextResult(SQLServerStatement.java:1515)
    at com.microsoft.sqlserver.jdbc.SQLServerPreparedStatement.doExecutePreparedStatement(SQLServerPreparedStatement.java:404)
    at com.microsoft.sqlserver.jdbc.SQLServerPreparedStatement$PrepStmtExecCmd.doExecute(SQLServerPreparedStatement.java:350)
    at com.microsoft.sqlserver.jdbc.TDSCommand.execute(IOBuffer.java:5696)
    at com.microsoft.sqlserver.jdbc.SQLServerConnection.executeCommand(SQLServerConnection.java:1715)
    at com.microsoft.sqlserver.jdbc.SQLServerStatement.executeCommand(SQLServerStatement.java:180)
    at com.microsoft.sqlserver.jdbc.SQLServerStatement.executeStatement(SQLServerStatement.java:155)
    at com.microsoft.sqlserver.jdbc.SQLServerPreparedStatement.executeUpdate(SQLServerPreparedStatement.java:314)
    at org.apache.commons.dbcp2.DelegatingPreparedStatement.executeUpdate(DelegatingPreparedStatement.java:98)
    at org.apache.commons.dbcp2.DelegatingPreparedStatement.executeUpdate(DelegatingPreparedStatement.java:98)
    at org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.executeUpdate(ResultSetReturnImpl.java:208)
    ... 22 more

1 个答案:

答案 0 :(得分:1)

当您调用persist()save()时,不会出现堆栈跟踪应显示的异常。它在调用flush()时发生,即实际执行SQL插入语句时。并且在事务提交之前自动调用flush()

你可以明确地调用flush()并捕获异常,但这将是无用的,因为Hibernate异常是不可恢复的。他们让会话处于无法使用的状态。面对这样的异常时唯一安全的做法是回滚事务并关闭会话。

做正确的事情:在尝试插入之前,使用自动生成的主键和/或使用查询检查数据是否不存在。