2015-02-23 125 views
0

我使用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("[email protected]"); 
     user.setFirstName("Md"); 
     user.setMiddleName("Sharique"); 
     user.setLastName("Alam"); 
     user.setId(1); 
     user.setPassword("123"); 
     user.setUserName("shariquealam01"); 
     userDaoService.saveUser(user); 
    } 
} 

@Service

public class UserDaoService { 
    @Autowired 
    public UserDao userDao; 

    @Transactional 
    public void saveUser(User user){ 
     System.out.println("User Saving"); 
     /*user.setActive(true); 
     user.setEmail("[email protected]"); 
     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 
+0

發佈其中一個「DataIntegrityViolationException」的完整堆棧跟蹤。 – 2015-02-23 16:54:12

+0

另外,請發佈您的excaption處理方法。試着先趕上'Exception',然後記錄它的類,然後相應地修改你的catch塊。 – bpgergo 2015-02-23 16:56:35

+0

顯示您的try catch語句。 – CKing 2015-02-23 16:56:55

回答

1

例外,如堆棧跟蹤應該顯示,當你調用persist()save()不會發生。發生在調用flush()時,即SQL插入語句實際執行時。在事務提交之前自動調用flush()

您可以明確地調用flush()並捕獲異常,但這是沒用的,因爲Hibernate異常是不可恢復的。他們使會議處於無法使用的狀態。遇到這種異常時唯一可以安全做的事情是回滾事務並關閉會話。

所以做正確的事情:在嘗試插入它之前,使用自動生成的主鍵和/或使用查詢來檢查數據是否存在。

+0

謝謝,對於建議.... 所以這意味着我無法處理這個在道和服務層的例外,對嗎? – Sharique 2015-02-23 17:16:53

+0

你可以,但唯一安全的做法是回滾,關閉會話,並拋出一個運行時異常來指示問題的調用者。所以這並不會增加你已經做的任何事情:讓原來的例外泡沫。 – 2015-02-23 17:23:08