mirror of
https://github.com/spring-projects/spring-framework.git
synced 2026-09-17 08:24:13 +00:00
Merge branch '7.0.x'
This commit is contained in:
+34
-6
@@ -259,10 +259,19 @@ public abstract class SharedEntityManagerCreator {
|
||||
Object result = method.invoke(target, args);
|
||||
if (result instanceof Query query) {
|
||||
if (newTarget) {
|
||||
InvocationHandler ih = new DeferredQueryInvocationHandler(query, target);
|
||||
Class<?>[] ifcs = cachedQueryInterfaces.computeIfAbsent(query.getClass(), key ->
|
||||
ClassUtils.getAllInterfacesForClass(key, this.proxyClassLoader));
|
||||
result = Proxy.newProxyInstance(this.proxyClassLoader, ifcs,
|
||||
new DeferredQueryInvocationHandler(query, target));
|
||||
try {
|
||||
result = Proxy.newProxyInstance(this.proxyClassLoader, ifcs, ih);
|
||||
}
|
||||
catch (IllegalArgumentException ex) {
|
||||
// Hibernate 8.0 NativeMutationOrSelectionQueryImpl multi-interface mismatch?
|
||||
// Fall back to single declared interface from method signature.
|
||||
Class<?>[] singleIfc = new Class<?>[] {method.getReturnType()};
|
||||
cachedQueryInterfaces.put(query.getClass(), singleIfc);
|
||||
result = Proxy.newProxyInstance(this.proxyClassLoader, singleIfc, ih);
|
||||
}
|
||||
close = false;
|
||||
}
|
||||
else {
|
||||
@@ -523,7 +532,7 @@ public abstract class SharedEntityManagerCreator {
|
||||
|
||||
private @Nullable Map<@Nullable Object, @Nullable Object> outputParameters;
|
||||
|
||||
public DeferredQueryInvocationHandler(Query target, Object entityHandler) {
|
||||
public DeferredQueryInvocationHandler(Query target, @Nullable Object entityHandler) {
|
||||
this.target = target;
|
||||
this.entityHandler = entityHandler;
|
||||
}
|
||||
@@ -551,7 +560,11 @@ public abstract class SharedEntityManagerCreator {
|
||||
return proxy;
|
||||
}
|
||||
else {
|
||||
return this.target.unwrap(targetClass);
|
||||
Object retVal = this.target.unwrap(targetClass);
|
||||
if (retVal instanceof Query query && targetClass.isInterface()) {
|
||||
retVal = adaptQueryProxy(proxy, query, targetClass);
|
||||
}
|
||||
return retVal;
|
||||
}
|
||||
}
|
||||
case "getOutputParameterValue" -> {
|
||||
@@ -572,14 +585,21 @@ public abstract class SharedEntityManagerCreator {
|
||||
// Invoke method on actual Query object.
|
||||
try {
|
||||
Object retVal = method.invoke(this.target, args);
|
||||
if (method.getName().equals("registerStoredProcedureParameter") && args.length == 3 &&
|
||||
Class<?> returnType = method.getReturnType();
|
||||
if (retVal == this.target && returnType.isInstance(proxy)) {
|
||||
retVal = proxy;
|
||||
}
|
||||
else if (retVal instanceof Query query) {
|
||||
retVal = adaptQueryProxy(proxy, query, returnType);
|
||||
}
|
||||
else if (method.getName().equals("registerStoredProcedureParameter") && args.length == 3 &&
|
||||
(args[2] == ParameterMode.OUT || args[2] == ParameterMode.INOUT)) {
|
||||
if (this.outputParameters == null) {
|
||||
this.outputParameters = new LinkedHashMap<>();
|
||||
}
|
||||
this.outputParameters.put(args[0], null);
|
||||
}
|
||||
return (retVal == this.target ? proxy : retVal);
|
||||
return retVal;
|
||||
}
|
||||
catch (InvocationTargetException ex) {
|
||||
throw ex.getTargetException();
|
||||
@@ -609,6 +629,14 @@ public abstract class SharedEntityManagerCreator {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private Object adaptQueryProxy(Object proxy, Query query, Class<?> expectedType) {
|
||||
InvocationHandler ih = this;
|
||||
if (query != this.target) {
|
||||
ih = new DeferredQueryInvocationHandler(query, this.entityHandler);
|
||||
}
|
||||
return Proxy.newProxyInstance(proxy.getClass().getClassLoader(), new Class<?>[] {expectedType}, ih);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user