Merge branch '6.2.x'
This commit is contained in:
commit
6927e39e6b
|
@ -453,7 +453,7 @@ public abstract class CacheAspectSupport extends AbstractCacheInvoker
|
||||||
() -> {
|
() -> {
|
||||||
CompletableFuture<?> invokeResult = ((CompletableFuture<?>) invokeOperation(invoker));
|
CompletableFuture<?> invokeResult = ((CompletableFuture<?>) invokeOperation(invoker));
|
||||||
if (invokeResult == null) {
|
if (invokeResult == null) {
|
||||||
return null;
|
throw new IllegalStateException("Returned CompletableFuture must not be null: " + method);
|
||||||
}
|
}
|
||||||
return invokeResult.exceptionallyCompose(ex -> {
|
return invokeResult.exceptionallyCompose(ex -> {
|
||||||
invokeFailure.set(true);
|
invokeFailure.set(true);
|
||||||
|
|
|
@ -130,15 +130,14 @@ public class ReflectiveRuntimeHintsRegistrar {
|
||||||
|
|
||||||
private ReflectiveProcessor instantiateClass(Class<? extends ReflectiveProcessor> type) {
|
private ReflectiveProcessor instantiateClass(Class<? extends ReflectiveProcessor> type) {
|
||||||
try {
|
try {
|
||||||
Constructor<? extends ReflectiveProcessor> constructor = type.getDeclaredConstructor();
|
return ReflectionUtils.accessibleConstructor(type).newInstance();
|
||||||
ReflectionUtils.makeAccessible(constructor);
|
|
||||||
return constructor.newInstance();
|
|
||||||
}
|
}
|
||||||
catch (Exception ex) {
|
catch (Exception ex) {
|
||||||
throw new IllegalStateException("Failed to instantiate " + type, ex);
|
throw new IllegalStateException("Failed to instantiate " + type, ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private static class DelegatingReflectiveProcessor implements ReflectiveProcessor {
|
private static class DelegatingReflectiveProcessor implements ReflectiveProcessor {
|
||||||
|
|
||||||
private final Iterable<ReflectiveProcessor> processors;
|
private final Iterable<ReflectiveProcessor> processors;
|
||||||
|
@ -151,9 +150,10 @@ public class ReflectiveRuntimeHintsRegistrar {
|
||||||
public void registerReflectionHints(ReflectionHints hints, AnnotatedElement element) {
|
public void registerReflectionHints(ReflectionHints hints, AnnotatedElement element) {
|
||||||
this.processors.forEach(processor -> processor.registerReflectionHints(hints, element));
|
this.processors.forEach(processor -> processor.registerReflectionHints(hints, element));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private record Entry(AnnotatedElement element, ReflectiveProcessor processor) {}
|
|
||||||
|
private record Entry(AnnotatedElement element, ReflectiveProcessor processor) {
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,7 +18,6 @@ package org.springframework.core.io.support;
|
||||||
|
|
||||||
import java.io.FileNotFoundException;
|
import java.io.FileNotFoundException;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.lang.reflect.Constructor;
|
|
||||||
import java.net.SocketException;
|
import java.net.SocketException;
|
||||||
import java.net.UnknownHostException;
|
import java.net.UnknownHostException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
@ -147,9 +146,7 @@ public class PropertySourceProcessor {
|
||||||
|
|
||||||
private static PropertySourceFactory instantiateClass(Class<? extends PropertySourceFactory> type) {
|
private static PropertySourceFactory instantiateClass(Class<? extends PropertySourceFactory> type) {
|
||||||
try {
|
try {
|
||||||
Constructor<? extends PropertySourceFactory> constructor = type.getDeclaredConstructor();
|
return ReflectionUtils.accessibleConstructor(type).newInstance();
|
||||||
ReflectionUtils.makeAccessible(constructor);
|
|
||||||
return constructor.newInstance();
|
|
||||||
}
|
}
|
||||||
catch (Exception ex) {
|
catch (Exception ex) {
|
||||||
throw new IllegalStateException("Failed to instantiate " + type, ex);
|
throw new IllegalStateException("Failed to instantiate " + type, ex);
|
||||||
|
|
|
@ -71,6 +71,11 @@ public class SQLStateSQLExceptionTranslator extends AbstractFallbackSQLException
|
||||||
"44" // With check violation
|
"44" // With check violation
|
||||||
);
|
);
|
||||||
|
|
||||||
|
private static final Set<String> PESSIMISTIC_LOCKING_FAILURE_CODES = Set.of(
|
||||||
|
"40", // Transaction rollback
|
||||||
|
"61" // Oracle: deadlock
|
||||||
|
);
|
||||||
|
|
||||||
private static final Set<String> DATA_ACCESS_RESOURCE_FAILURE_CODES = Set.of(
|
private static final Set<String> DATA_ACCESS_RESOURCE_FAILURE_CODES = Set.of(
|
||||||
"08", // Connection exception
|
"08", // Connection exception
|
||||||
"53", // PostgreSQL: insufficient resources (for example, disk full)
|
"53", // PostgreSQL: insufficient resources (for example, disk full)
|
||||||
|
@ -85,11 +90,6 @@ public class SQLStateSQLExceptionTranslator extends AbstractFallbackSQLException
|
||||||
"S1" // DB2: communication failure
|
"S1" // DB2: communication failure
|
||||||
);
|
);
|
||||||
|
|
||||||
private static final Set<String> PESSIMISTIC_LOCKING_FAILURE_CODES = Set.of(
|
|
||||||
"40", // Transaction rollback
|
|
||||||
"61" // Oracle: deadlock
|
|
||||||
);
|
|
||||||
|
|
||||||
private static final Set<Integer> DUPLICATE_KEY_ERROR_CODES = Set.of(
|
private static final Set<Integer> DUPLICATE_KEY_ERROR_CODES = Set.of(
|
||||||
1, // Oracle
|
1, // Oracle
|
||||||
301, // SAP HANA
|
301, // SAP HANA
|
||||||
|
@ -117,18 +117,21 @@ public class SQLStateSQLExceptionTranslator extends AbstractFallbackSQLException
|
||||||
}
|
}
|
||||||
return new DataIntegrityViolationException(buildMessage(task, sql, ex), ex);
|
return new DataIntegrityViolationException(buildMessage(task, sql, ex), ex);
|
||||||
}
|
}
|
||||||
else if (DATA_ACCESS_RESOURCE_FAILURE_CODES.contains(classCode)) {
|
|
||||||
return new DataAccessResourceFailureException(buildMessage(task, sql, ex), ex);
|
|
||||||
}
|
|
||||||
else if (TRANSIENT_DATA_ACCESS_RESOURCE_CODES.contains(classCode)) {
|
|
||||||
return new TransientDataAccessResourceException(buildMessage(task, sql, ex), ex);
|
|
||||||
}
|
|
||||||
else if (PESSIMISTIC_LOCKING_FAILURE_CODES.contains(classCode)) {
|
else if (PESSIMISTIC_LOCKING_FAILURE_CODES.contains(classCode)) {
|
||||||
if (indicatesCannotAcquireLock(sqlState)) {
|
if (indicatesCannotAcquireLock(sqlState)) {
|
||||||
return new CannotAcquireLockException(buildMessage(task, sql, ex), ex);
|
return new CannotAcquireLockException(buildMessage(task, sql, ex), ex);
|
||||||
}
|
}
|
||||||
return new PessimisticLockingFailureException(buildMessage(task, sql, ex), ex);
|
return new PessimisticLockingFailureException(buildMessage(task, sql, ex), ex);
|
||||||
}
|
}
|
||||||
|
else if (DATA_ACCESS_RESOURCE_FAILURE_CODES.contains(classCode)) {
|
||||||
|
if (indicatesQueryTimeout(sqlState)) {
|
||||||
|
return new QueryTimeoutException(buildMessage(task, sql, ex), ex);
|
||||||
|
}
|
||||||
|
return new DataAccessResourceFailureException(buildMessage(task, sql, ex), ex);
|
||||||
|
}
|
||||||
|
else if (TRANSIENT_DATA_ACCESS_RESOURCE_CODES.contains(classCode)) {
|
||||||
|
return new TransientDataAccessResourceException(buildMessage(task, sql, ex), ex);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// For MySQL: exception class name indicating a timeout?
|
// For MySQL: exception class name indicating a timeout?
|
||||||
|
@ -183,4 +186,13 @@ public class SQLStateSQLExceptionTranslator extends AbstractFallbackSQLException
|
||||||
return "40001".equals(sqlState);
|
return "40001".equals(sqlState);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check whether the given SQL state indicates a {@link QueryTimeoutException},
|
||||||
|
* with SQL state 57014 as a specific indication.
|
||||||
|
* @param sqlState the SQL state value
|
||||||
|
*/
|
||||||
|
static boolean indicatesQueryTimeout(@Nullable String sqlState) {
|
||||||
|
return "57014".equals(sqlState);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,6 +27,7 @@ import org.springframework.dao.DataAccessResourceFailureException;
|
||||||
import org.springframework.dao.DataIntegrityViolationException;
|
import org.springframework.dao.DataIntegrityViolationException;
|
||||||
import org.springframework.dao.DuplicateKeyException;
|
import org.springframework.dao.DuplicateKeyException;
|
||||||
import org.springframework.dao.PessimisticLockingFailureException;
|
import org.springframework.dao.PessimisticLockingFailureException;
|
||||||
|
import org.springframework.dao.QueryTimeoutException;
|
||||||
import org.springframework.dao.TransientDataAccessResourceException;
|
import org.springframework.dao.TransientDataAccessResourceException;
|
||||||
import org.springframework.jdbc.BadSqlGrammarException;
|
import org.springframework.jdbc.BadSqlGrammarException;
|
||||||
|
|
||||||
|
@ -109,6 +110,11 @@ class SQLStateSQLExceptionTranslatorTests {
|
||||||
assertTranslation("40001", CannotAcquireLockException.class);
|
assertTranslation("40001", CannotAcquireLockException.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void translateQueryTimeout() {
|
||||||
|
assertTranslation("57014", QueryTimeoutException.class);
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void translateUncategorized() {
|
void translateUncategorized() {
|
||||||
assertTranslation("00000000", null);
|
assertTranslation("00000000", null);
|
||||||
|
|
Loading…
Reference in New Issue