從org.springframework.dao.DuplicateKeyException提及

Spring MyBatis的異常處理

一般在dao層將全部異常轉嫁到Spring的RuntimeException體系(org.springframework.dao.DataAccessException)中來。 如:spring

try {  
    vehicleDAO.insert(vehicle);  
} catch (DataAccessException e) {  
    SQLException sqle = (SQLException) e.getCause();  
    System.out.println("Error code: " + sqle.getErrorCode());  
    System.out.println("SQL state: " + sqle.getSQLState());  
}

咱們能夠獲取狀態碼和SQL狀態。 這樣就知道了這個錯誤的具體含義,好比104:惟一約束驗證失敗。這就是咱們故意設置的重複主鍵問題。sql

Spring的JDBC模塊爲咱們預約義了一些錯誤代碼,它存儲在org.springframework.jdbc.support包下的sql-error-codes.xml文件中,其中描述HSQL的內容爲:數據庫

<bean id="HSQL" class="org.springframework.jdbc.support.SQLErrorCodes">  
    <property name="databaseProductName">  
        <value>HSQL Database Engine</value>  
    </property>  
    <property name="badSqlGrammarCodes">  
        <value>-22,-28</value>  
    </property>  
    <property name="duplicateKeyCodes">  
        <value>-104</value>  
    </property>  
    <property name="dataIntegrityViolationCodes">  
        <value>-9</value>  
    </property>  
    <property name="dataAccessResourceFailureCodes">  
        <value>-80</value>  
    </property>  
</bean>

上面咱們已經知道在org.springframework.jdbc.support包下有sql-error-codes.xml文件,在Spring啓動時會自動讀取這個文件中的錯誤碼,它爲咱們預分類了一些錯誤碼,而咱們能夠增強它,來使用咱們自定義的異常。工具

首先,定義一個異常類,咱們就來自定義一下前面的-104錯誤,就是HSQL的重複鍵的問題:code

package org.ourpioneer.vehicle.exception;  
import org.springframework.dao.DataIntegrityViolationException;  
public class VehicleDuplicateKeyException extends  
        DataIntegrityViolationException {  
    public VehicleDuplicateKeyException(String msg) {  
        super(msg);  
    }  
    public VehicleDuplicateKeyException(String msg, Throwable cause) {  
        super(msg, cause);  
    }  
}

以後咱們從新新建一個sql-error-codes.xml代碼,並將它放到類路徑的根目錄下,這樣Spring會發現它並使用咱們自定義的文件,在配置中定義以下:xml

<bean id="HSQL" class="org.springframework.jdbc.support.SQLErrorCodes">  
        <property name="databaseProductName" value="HSQL Database Engine" />  
        <property name="useSqlStateForTranslation" value="false" />  
        <property name="customTranslations">  
            <list>  
                <ref local="vehicleDuplicateKeyTranslation" />  
            </list>  
        </property>  
    </bean>  
    <bean id="vehicleDuplicateKeyTranslation"  
    class="org.springframework.jdbc.support.CustomSQLErrorCodesTranslation">  
        <property name="errorCodes" value="-104" />  
        <property name="exceptionClass"  
    value="org.ourpioneer.vehicle.exception.VehicleDuplicateKeyException" />  
</bean>

以後就可使用咱們本身定義的異常類了。出現異常後,VehicleDuplicateKeyException就拋出了。 DataAccessException是RuntimeException,是無需檢查的異常,不要求進行代碼處理。事務

Spring的Dao拋上來的異常一般有:

  • CleanupFailureDataAccessException 一項操做成功地執行,但在釋放數據庫資源時發生異常(例如,關閉一個Connection)
  • DataAccessResourceFailureException 數據訪問資源完全失敗,例如不能鏈接數據庫
  • DataIntegrityViolationException Insert或Update數據時違反了完整性,例如違反了唯一性限制
  • DataRetrievalFailureException 某些數據不能被檢測到,例如不能經過關鍵字找到一條記錄
  • DeadlockLoserDataAccessException 當前的操做由於死鎖而失敗
  • IncorrectUpdateSemanticsDataAccessException Update時發生某些沒有預料到的狀況,例如更改超過預期的記錄數。當這個異常被拋出時,執行着的事務不會被回滾
  • InvalidDataAccessApiusageException 一個數據訪問的JAVA API沒有正確使用,例如必須在執行前編譯好的查詢編譯失敗了
  • InvalidDataAccessResourceUsageException 錯誤使用數據訪問資源,例如用錯誤的SQL語法訪問關係型數據庫
  • OptimisticLockingFailureException 樂觀鎖的失敗。這將由ORM工具或用戶的DAO實現拋出
  • TypemismatchDataAccessException Java類型和數據類型不匹配,例如試圖把String類型插入到數據庫的數值型字段中
  • UncategorizedDataAccessException 有錯誤發生,但沒法歸類到某一更爲具體的異常中

這樣服務層能夠精確的捕獲異常,或者向上繼續拋出異常。資源


更多內容關注: get

相關文章
相關標籤/搜索