1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.mybatis.spring;
17
18 import java.sql.SQLException;
19 import java.util.function.Supplier;
20
21 import javax.sql.DataSource;
22
23 import org.apache.ibatis.exceptions.PersistenceException;
24 import org.springframework.dao.DataAccessException;
25 import org.springframework.dao.support.PersistenceExceptionTranslator;
26 import org.springframework.jdbc.UncategorizedSQLException;
27 import org.springframework.jdbc.support.SQLErrorCodeSQLExceptionTranslator;
28 import org.springframework.jdbc.support.SQLExceptionTranslator;
29 import org.springframework.transaction.TransactionException;
30
31
32
33
34
35
36
37
38
39
40 public class MyBatisExceptionTranslator implements PersistenceExceptionTranslator {
41
42 private final Supplier<SQLExceptionTranslator> exceptionTranslatorSupplier;
43 private SQLExceptionTranslator exceptionTranslator;
44
45
46
47
48
49
50
51
52
53
54 public MyBatisExceptionTranslator(DataSource dataSource, boolean exceptionTranslatorLazyInit) {
55 this(() -> new SQLErrorCodeSQLExceptionTranslator(dataSource), exceptionTranslatorLazyInit);
56 }
57
58
59
60
61
62
63
64
65
66
67
68
69 public MyBatisExceptionTranslator(Supplier<SQLExceptionTranslator> exceptionTranslatorSupplier,
70 boolean exceptionTranslatorLazyInit) {
71 this.exceptionTranslatorSupplier = exceptionTranslatorSupplier;
72 if (!exceptionTranslatorLazyInit) {
73 this.initExceptionTranslator();
74 }
75 }
76
77
78
79
80 @Override
81 public DataAccessException translateExceptionIfPossible(RuntimeException e) {
82 if (e instanceof PersistenceException) {
83
84
85 if (e.getCause() instanceof PersistenceException) {
86 e = (PersistenceException) e.getCause();
87 }
88 if (e.getCause() instanceof SQLException) {
89 this.initExceptionTranslator();
90 String task = e.getMessage() + "\n";
91 SQLException se = (SQLException) e.getCause();
92 DataAccessException dae = this.exceptionTranslator.translate(task, null, se);
93 return dae != null ? dae : new UncategorizedSQLException(task, null, se);
94 } else if (e.getCause() instanceof TransactionException) {
95 throw (TransactionException) e.getCause();
96 }
97 return new MyBatisSystemException(e);
98 }
99 return null;
100 }
101
102
103
104
105 private synchronized void initExceptionTranslator() {
106 if (this.exceptionTranslator == null) {
107 this.exceptionTranslator = exceptionTranslatorSupplier.get();
108 }
109 }
110
111 }