Avoid proxy replacement for generic return type signatures

Issue: SPR-15010
(cherry picked from commit 6d1cae2)
This commit is contained in:
Juergen Hoeller 2016-12-14 22:00:41 +01:00
parent f3cc4ab09d
commit d15df3489e
3 changed files with 19 additions and 3 deletions

View File

@ -351,7 +351,8 @@ class CglibAopProxy implements AopProxy, Serializable {
*/
private static Object processReturnType(Object proxy, Object target, Method method, Object retVal) {
// Massage return value if necessary
if (retVal != null && retVal == target && !RawTargetAccess.class.isAssignableFrom(method.getDeclaringClass())) {
if (retVal != null && retVal == target &&
!RawTargetAccess.class.isAssignableFrom(method.getDeclaringClass())) {
// Special case: it returned "this". Note that we can't help
// if the target sets a reference to itself in another returned object.
retVal = proxy;

View File

@ -215,7 +215,8 @@ final class JdkDynamicAopProxy implements AopProxy, InvocationHandler, Serializa
// Massage return value if necessary.
Class<?> returnType = method.getReturnType();
if (retVal != null && retVal == target && returnType.isInstance(proxy) &&
if (retVal != null && retVal == target &&
returnType != Object.class && returnType.isInstance(proxy) &&
!RawTargetAccess.class.isAssignableFrom(method.getDeclaringClass())) {
// Special case: it returned "this" and the return type of the method
// is type-compatible. Note that we can't help if the target sets

View File

@ -1,5 +1,5 @@
/*
* Copyright 2002-2015 the original author or authors.
* Copyright 2002-2016 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -16,9 +16,13 @@
package org.springframework.orm.jpa.hibernate;
import javax.persistence.EntityManager;
import org.hibernate.ejb.HibernateEntityManager;
import org.hibernate.ejb.HibernateEntityManagerFactory;
import org.springframework.aop.framework.ProxyFactory;
import org.springframework.aop.target.SingletonTargetSource;
import org.springframework.orm.jpa.AbstractContainerEntityManagerFactoryIntegrationTests;
import org.springframework.orm.jpa.EntityManagerFactoryInfo;
@ -48,4 +52,14 @@ public class HibernateEntityManagerFactoryIntegrationTests extends
assertNotNull(hibernateEntityManager.getSession());
}
public void testCanUnwrapAopProxy() {
EntityManager em = entityManagerFactory.createEntityManager();
EntityManager proxy = ProxyFactory.getProxy(EntityManager.class, new SingletonTargetSource(em));
assertTrue(em instanceof HibernateEntityManager);
assertFalse(proxy instanceof HibernateEntityManager);
assertTrue(proxy.unwrap(HibernateEntityManager.class) instanceof HibernateEntityManager);
assertSame(em, proxy.unwrap(HibernateEntityManager.class));
assertSame(em.getDelegate(), proxy.getDelegate());
}
}