001package io.ebean.config.dbplatform; 002 003import io.ebean.AcquireLockException; 004import io.ebean.DataIntegrityException; 005import io.ebean.DuplicateKeyException; 006import io.ebean.SerializableConflictException; 007 008import javax.persistence.PersistenceException; 009import java.sql.SQLException; 010import java.util.Collections; 011import java.util.Map; 012 013/** 014 * Translate SQLException based on SQLState codes. 015 */ 016public class SqlCodeTranslator implements SqlExceptionTranslator { 017 018 private final Map<String, DataErrorType> map; 019 020 /** 021 * Create given the map of SQLState codes to error types. 022 */ 023 public SqlCodeTranslator(Map<String, DataErrorType> map) { 024 this.map = map; 025 } 026 027 /** 028 * Create "No-op" implementation. 029 */ 030 public SqlCodeTranslator() { 031 this.map = Collections.emptyMap(); 032 } 033 034 @Override 035 public PersistenceException translate(String message, SQLException e) { 036 037 DataErrorType errorType = map.get(e.getSQLState()); 038 if (errorType == null) { 039 // fall back to error code 040 errorType = map.get(String.valueOf(e.getErrorCode())); 041 } 042 if (errorType != null) { 043 switch (errorType) { 044 case AcquireLock: 045 return new AcquireLockException(message, e); 046 case DuplicateKey: 047 return new DuplicateKeyException(message, e); 048 case DataIntegrity: 049 return new DataIntegrityException(message, e); 050 case SerializableConflict: 051 return new SerializableConflictException(message, e); 052 } 053 } 054 // return a generic exception 055 return new PersistenceException(message, e); 056 } 057}