Skip to content

Commit

Permalink
Avoid proxy replacement for generic return type signatures
Browse files Browse the repository at this point in the history
Issue: SPR-15010
  • Loading branch information
jhoeller committed Dec 14, 2016
1 parent 58eccfe commit 6d1cae2
Show file tree
Hide file tree
Showing 3 changed files with 24 additions and 2 deletions.
Expand Up @@ -351,7 +351,8 @@ private Callback[] getCallbacks(Class<?> rootClass) throws Exception {
*/
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;
Expand Down
Expand Up @@ -215,7 +215,8 @@ else if (!this.advised.opaque && method.getDeclaringClass().isInterface() &&

// 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
Expand Down
Expand Up @@ -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;
Expand All @@ -32,6 +38,7 @@
* @author Juergen Hoeller
* @author Rod Johnson
*/
@SuppressWarnings("deprecation")
public class HibernateEntityManagerFactoryIntegrationTests extends AbstractContainerEntityManagerFactoryIntegrationTests {

@Override
Expand All @@ -43,12 +50,25 @@ protected String[] getConfigLocations() {
@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());
}

}

0 comments on commit 6d1cae2

Please sign in to comment.