diff --git a/spring-aop/src/main/java/org/springframework/aop/framework/CglibAopProxy.java b/spring-aop/src/main/java/org/springframework/aop/framework/CglibAopProxy.java index 3fb3d20b9a7..a708e7bb88b 100644 --- a/spring-aop/src/main/java/org/springframework/aop/framework/CglibAopProxy.java +++ b/spring-aop/src/main/java/org/springframework/aop/framework/CglibAopProxy.java @@ -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; diff --git a/spring-aop/src/main/java/org/springframework/aop/framework/JdkDynamicAopProxy.java b/spring-aop/src/main/java/org/springframework/aop/framework/JdkDynamicAopProxy.java index 1f90b0b5732..c280830a14f 100644 --- a/spring-aop/src/main/java/org/springframework/aop/framework/JdkDynamicAopProxy.java +++ b/spring-aop/src/main/java/org/springframework/aop/framework/JdkDynamicAopProxy.java @@ -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 diff --git a/spring-orm/src/test/java/org/springframework/orm/jpa/hibernate/HibernateEntityManagerFactoryIntegrationTests.java b/spring-orm/src/test/java/org/springframework/orm/jpa/hibernate/HibernateEntityManagerFactoryIntegrationTests.java index c9e2af42a4d..0da28ee086c 100644 --- a/spring-orm/src/test/java/org/springframework/orm/jpa/hibernate/HibernateEntityManagerFactoryIntegrationTests.java +++ b/spring-orm/src/test/java/org/springframework/orm/jpa/hibernate/HibernateEntityManagerFactoryIntegrationTests.java @@ -16,10 +16,16 @@ package org.springframework.orm.jpa.hibernate; +import javax.persistence.EntityManager; + import org.hibernate.Session; import org.hibernate.SessionFactory; +import org.hibernate.jpa.HibernateEntityManager; +import org.hibernate.jpa.HibernateEntityManagerFactory; 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.EntityManagerFactoryInfo; import org.springframework.orm.jpa.EntityManagerProxy; @@ -32,6 +38,7 @@ import static org.junit.Assert.*; * @author Juergen Hoeller * @author Rod Johnson */ +@SuppressWarnings("deprecation") public class HibernateEntityManagerFactoryIntegrationTests extends AbstractContainerEntityManagerFactoryIntegrationTests { @Override @@ -43,12 +50,25 @@ public class HibernateEntityManagerFactoryIntegrationTests extends AbstractConta @Test public void testCanCastNativeEntityManagerFactoryToHibernateEntityManagerFactoryImpl() { EntityManagerFactoryInfo emfi = (EntityManagerFactoryInfo) entityManagerFactory; + assertTrue(emfi.getNativeEntityManagerFactory() instanceof HibernateEntityManagerFactory); assertTrue(emfi.getNativeEntityManagerFactory() instanceof SessionFactory); // as of Hibernate 5.2 } @Test public void testCanCastSharedEntityManagerProxyToHibernateEntityManager() { + assertTrue(sharedEntityManager instanceof HibernateEntityManager); 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()); + } + }