Skip to content

Commit 6d1cae2

Browse files
committed
Avoid proxy replacement for generic return type signatures
Issue: SPR-15010
1 parent 58eccfe commit 6d1cae2

File tree

3 files changed

+24
-2
lines changed

3 files changed

+24
-2
lines changed

spring-aop/src/main/java/org/springframework/aop/framework/CglibAopProxy.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -351,7 +351,8 @@ private Callback[] getCallbacks(Class<?> rootClass) throws Exception {
351351
*/
352352
private static Object processReturnType(Object proxy, Object target, Method method, Object retVal) {
353353
// Massage return value if necessary
354-
if (retVal != null && retVal == target && !RawTargetAccess.class.isAssignableFrom(method.getDeclaringClass())) {
354+
if (retVal != null && retVal == target &&
355+
!RawTargetAccess.class.isAssignableFrom(method.getDeclaringClass())) {
355356
// Special case: it returned "this". Note that we can't help
356357
// if the target sets a reference to itself in another returned object.
357358
retVal = proxy;

spring-aop/src/main/java/org/springframework/aop/framework/JdkDynamicAopProxy.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -215,7 +215,8 @@ else if (!this.advised.opaque && method.getDeclaringClass().isInterface() &&
215215

216216
// Massage return value if necessary.
217217
Class<?> returnType = method.getReturnType();
218-
if (retVal != null && retVal == target && returnType.isInstance(proxy) &&
218+
if (retVal != null && retVal == target &&
219+
returnType != Object.class && returnType.isInstance(proxy) &&
219220
!RawTargetAccess.class.isAssignableFrom(method.getDeclaringClass())) {
220221
// Special case: it returned "this" and the return type of the method
221222
// is type-compatible. Note that we can't help if the target sets

spring-orm/src/test/java/org/springframework/orm/jpa/hibernate/HibernateEntityManagerFactoryIntegrationTests.java

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,16 @@
1616

1717
package org.springframework.orm.jpa.hibernate;
1818

19+
import javax.persistence.EntityManager;
20+
1921
import org.hibernate.Session;
2022
import org.hibernate.SessionFactory;
23+
import org.hibernate.jpa.HibernateEntityManager;
24+
import org.hibernate.jpa.HibernateEntityManagerFactory;
2125
import org.junit.Test;
2226

27+
import org.springframework.aop.framework.ProxyFactory;
28+
import org.springframework.aop.target.SingletonTargetSource;
2329
import org.springframework.orm.jpa.AbstractContainerEntityManagerFactoryIntegrationTests;
2430
import org.springframework.orm.jpa.EntityManagerFactoryInfo;
2531
import org.springframework.orm.jpa.EntityManagerProxy;
@@ -32,6 +38,7 @@
3238
* @author Juergen Hoeller
3339
* @author Rod Johnson
3440
*/
41+
@SuppressWarnings("deprecation")
3542
public class HibernateEntityManagerFactoryIntegrationTests extends AbstractContainerEntityManagerFactoryIntegrationTests {
3643

3744
@Override
@@ -43,12 +50,25 @@ protected String[] getConfigLocations() {
4350
@Test
4451
public void testCanCastNativeEntityManagerFactoryToHibernateEntityManagerFactoryImpl() {
4552
EntityManagerFactoryInfo emfi = (EntityManagerFactoryInfo) entityManagerFactory;
53+
assertTrue(emfi.getNativeEntityManagerFactory() instanceof HibernateEntityManagerFactory);
4654
assertTrue(emfi.getNativeEntityManagerFactory() instanceof SessionFactory); // as of Hibernate 5.2
4755
}
4856

4957
@Test
5058
public void testCanCastSharedEntityManagerProxyToHibernateEntityManager() {
59+
assertTrue(sharedEntityManager instanceof HibernateEntityManager);
5160
assertTrue(((EntityManagerProxy) sharedEntityManager).getTargetEntityManager() instanceof Session); // as of Hibernate 5.2
5261
}
5362

63+
@Test
64+
public void testCanUnwrapAopProxy() {
65+
EntityManager em = entityManagerFactory.createEntityManager();
66+
EntityManager proxy = ProxyFactory.getProxy(EntityManager.class, new SingletonTargetSource(em));
67+
assertTrue(em instanceof HibernateEntityManager);
68+
assertFalse(proxy instanceof HibernateEntityManager);
69+
assertTrue(proxy.unwrap(HibernateEntityManager.class) instanceof HibernateEntityManager);
70+
assertSame(em, proxy.unwrap(HibernateEntityManager.class));
71+
assertSame(em.getDelegate(), proxy.getDelegate());
72+
}
73+
5474
}

0 commit comments

Comments
 (0)