Avoid proxy replacement for generic return type signatures
Issue: SPR-15010
This commit is contained in:
		
							parent
							
								
									58eccfe5bd
								
							
						
					
					
						commit
						6d1cae2f57
					
				| 
						 | 
					@ -351,7 +351,8 @@ class CglibAopProxy implements AopProxy, Serializable {
 | 
				
			||||||
	 */
 | 
						 */
 | 
				
			||||||
	private static Object processReturnType(Object proxy, Object target, Method method, Object retVal) {
 | 
						private static Object processReturnType(Object proxy, Object target, Method method, Object retVal) {
 | 
				
			||||||
		// Massage return value if necessary
 | 
							// 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
 | 
								// Special case: it returned "this". Note that we can't help
 | 
				
			||||||
			// if the target sets a reference to itself in another returned object.
 | 
								// if the target sets a reference to itself in another returned object.
 | 
				
			||||||
			retVal = proxy;
 | 
								retVal = proxy;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -215,7 +215,8 @@ final class JdkDynamicAopProxy implements AopProxy, InvocationHandler, Serializa
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			// Massage return value if necessary.
 | 
								// Massage return value if necessary.
 | 
				
			||||||
			Class<?> returnType = method.getReturnType();
 | 
								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())) {
 | 
										!RawTargetAccess.class.isAssignableFrom(method.getDeclaringClass())) {
 | 
				
			||||||
				// Special case: it returned "this" and the return type of the method
 | 
									// 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
 | 
									// is type-compatible. Note that we can't help if the target sets
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -16,10 +16,16 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
package org.springframework.orm.jpa.hibernate;
 | 
					package org.springframework.orm.jpa.hibernate;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import javax.persistence.EntityManager;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import org.hibernate.Session;
 | 
					import org.hibernate.Session;
 | 
				
			||||||
import org.hibernate.SessionFactory;
 | 
					import org.hibernate.SessionFactory;
 | 
				
			||||||
 | 
					import org.hibernate.jpa.HibernateEntityManager;
 | 
				
			||||||
 | 
					import org.hibernate.jpa.HibernateEntityManagerFactory;
 | 
				
			||||||
import org.junit.Test;
 | 
					import org.junit.Test;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import org.springframework.aop.framework.ProxyFactory;
 | 
				
			||||||
 | 
					import org.springframework.aop.target.SingletonTargetSource;
 | 
				
			||||||
import org.springframework.orm.jpa.AbstractContainerEntityManagerFactoryIntegrationTests;
 | 
					import org.springframework.orm.jpa.AbstractContainerEntityManagerFactoryIntegrationTests;
 | 
				
			||||||
import org.springframework.orm.jpa.EntityManagerFactoryInfo;
 | 
					import org.springframework.orm.jpa.EntityManagerFactoryInfo;
 | 
				
			||||||
import org.springframework.orm.jpa.EntityManagerProxy;
 | 
					import org.springframework.orm.jpa.EntityManagerProxy;
 | 
				
			||||||
| 
						 | 
					@ -32,6 +38,7 @@ import static org.junit.Assert.*;
 | 
				
			||||||
 * @author Juergen Hoeller
 | 
					 * @author Juergen Hoeller
 | 
				
			||||||
 * @author Rod Johnson
 | 
					 * @author Rod Johnson
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
 | 
					@SuppressWarnings("deprecation")
 | 
				
			||||||
public class HibernateEntityManagerFactoryIntegrationTests extends AbstractContainerEntityManagerFactoryIntegrationTests {
 | 
					public class HibernateEntityManagerFactoryIntegrationTests extends AbstractContainerEntityManagerFactoryIntegrationTests {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	@Override
 | 
						@Override
 | 
				
			||||||
| 
						 | 
					@ -43,12 +50,25 @@ public class HibernateEntityManagerFactoryIntegrationTests extends AbstractConta
 | 
				
			||||||
	@Test
 | 
						@Test
 | 
				
			||||||
	public void testCanCastNativeEntityManagerFactoryToHibernateEntityManagerFactoryImpl() {
 | 
						public void testCanCastNativeEntityManagerFactoryToHibernateEntityManagerFactoryImpl() {
 | 
				
			||||||
		EntityManagerFactoryInfo emfi = (EntityManagerFactoryInfo) entityManagerFactory;
 | 
							EntityManagerFactoryInfo emfi = (EntityManagerFactoryInfo) entityManagerFactory;
 | 
				
			||||||
 | 
							assertTrue(emfi.getNativeEntityManagerFactory() instanceof HibernateEntityManagerFactory);
 | 
				
			||||||
		assertTrue(emfi.getNativeEntityManagerFactory() instanceof SessionFactory);  // as of Hibernate 5.2
 | 
							assertTrue(emfi.getNativeEntityManagerFactory() instanceof SessionFactory);  // as of Hibernate 5.2
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	@Test
 | 
						@Test
 | 
				
			||||||
	public void testCanCastSharedEntityManagerProxyToHibernateEntityManager() {
 | 
						public void testCanCastSharedEntityManagerProxyToHibernateEntityManager() {
 | 
				
			||||||
 | 
							assertTrue(sharedEntityManager instanceof HibernateEntityManager);
 | 
				
			||||||
		assertTrue(((EntityManagerProxy) sharedEntityManager).getTargetEntityManager() instanceof Session);  // as of Hibernate 5.2
 | 
							assertTrue(((EntityManagerProxy) sharedEntityManager).getTargetEntityManager() instanceof Session);  // as of Hibernate 5.2
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						@Test
 | 
				
			||||||
 | 
						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());
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue