-
Notifications
You must be signed in to change notification settings - Fork 186
/
HawkBitEclipseLinkJpaDialect.java
100 lines (88 loc) · 3.63 KB
/
HawkBitEclipseLinkJpaDialect.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
/**
* Copyright (c) 2015 Bosch Software Innovations GmbH and others
*
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
* which is available at https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*/
package org.eclipse.hawkbit.repository.jpa;
import java.sql.SQLException;
import jakarta.persistence.PersistenceException;
import org.springframework.dao.DataAccessException;
import org.springframework.jdbc.support.SQLStateSQLExceptionTranslator;
import org.springframework.lang.NonNull;
import org.springframework.orm.jpa.JpaSystemException;
import org.springframework.orm.jpa.vendor.EclipseLinkJpaDialect;
/**
* {@link EclipseLinkJpaDialect} with additional exception translation
* mechanisms based on {@link SQLStateSQLExceptionTranslator}.
*
* There are multiple variations of exceptions coming out of persistence
* provider:
*
* <p>
* 1) {@link PersistenceException}s that can be mapped by
* {@link EclipseLinkJpaDialect} into corresponding {@link DataAccessException}.
* <p>
* 2) {@link PersistenceException}s that could not be mapped by
* {@link EclipseLinkJpaDialect} directly but instead are wrapped into
* {@link JpaSystemException}.
* <p>
* 2.a) here the wrapped exception's causes might be an {@link SQLException}
* which might be mappable by {@link SQLStateSQLExceptionTranslator} or
* <p>
* 2.b.) the wrapped exception's causes due not contain an {@link SQLException}
* and as a result cannot be mapped.
* <p>
* 3) A {@link RuntimeException} that is no {@link PersistenceException}.
* <p>
* 3.a) here a cause might be an {@link SQLException} which might be mappable by
* {@link SQLStateSQLExceptionTranslator} or
* <p>
* 3.b.) the cause is not an {@link SQLException} and as a result cannot be
* mapped.
*
*/
public class HawkBitEclipseLinkJpaDialect extends EclipseLinkJpaDialect {
private static final long serialVersionUID = 1L;
private static final SQLStateSQLExceptionTranslator SQLSTATE_EXCEPTION_TRANSLATOR = new SQLStateSQLExceptionTranslator();
@Override
public DataAccessException translateExceptionIfPossible(@NonNull final RuntimeException ex) {
final DataAccessException dataAccessException = super.translateExceptionIfPossible(ex);
if (dataAccessException == null) {
return searchAndTranslateSqlException(ex);
}
return translateJpaSystemExceptionIfPossible(dataAccessException);
}
private static DataAccessException translateJpaSystemExceptionIfPossible(
final DataAccessException accessException) {
if (!(accessException instanceof JpaSystemException)) {
return accessException;
}
final DataAccessException sqlException = searchAndTranslateSqlException(accessException);
if (sqlException == null) {
return accessException;
}
return sqlException;
}
private static DataAccessException searchAndTranslateSqlException(final RuntimeException ex) {
final SQLException sqlException = findSqlException(ex);
if (sqlException == null) {
return null;
}
return SQLSTATE_EXCEPTION_TRANSLATOR.translate("", null, sqlException);
}
private static SQLException findSqlException(final RuntimeException jpaSystemException) {
Throwable exception = jpaSystemException;
do {
final Throwable cause = exception.getCause();
if (cause instanceof SQLException) {
return (SQLException) cause;
}
exception = cause;
} while (exception != null);
return null;
}
}