diff --git a/spring-orm/src/main/java/org/springframework/orm/jpa/AbstractEntityManagerFactoryBean.java b/spring-orm/src/main/java/org/springframework/orm/jpa/AbstractEntityManagerFactoryBean.java index 872ba91f37..4043bef01f 100644 --- a/spring-orm/src/main/java/org/springframework/orm/jpa/AbstractEntityManagerFactoryBean.java +++ b/spring-orm/src/main/java/org/springframework/orm/jpa/AbstractEntityManagerFactoryBean.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2014 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. @@ -33,6 +33,7 @@ import java.util.Set; import javax.persistence.EntityManager; import javax.persistence.EntityManagerFactory; import javax.persistence.PersistenceException; +import javax.persistence.Query; import javax.persistence.spi.PersistenceProvider; import javax.persistence.spi.PersistenceUnitInfo; import javax.sql.DataSource; @@ -384,6 +385,24 @@ public abstract class AbstractEntityManagerFactoryBean implements return ExtendedEntityManagerCreator.createApplicationManagedEntityManager(rawEntityManager, this, true); } + // Look for Query arguments, primarily JPA 2.1's addNamedQuery(String, Query) + if (args != null) { + for (int i = 0; i < args.length; i++) { + Object arg = args[i]; + if (arg instanceof Query && Proxy.isProxyClass(arg.getClass())) { + // Assumably a Spring-generated proxy from SharedEntityManagerCreator: + // since we're passing it back to the native EntityManagerFactory, + // let's unwrap it to the original Query object from the provider. + try { + args[i] = ((Query) arg).unwrap(null); + } + catch (RuntimeException ex) { + // Ignore - simply proceed with given Query object then + } + } + } + } + // Standard delegation to the native factory, just post-processing EntityManager return values Object retVal = method.invoke(this.nativeEntityManagerFactory, args); if (retVal instanceof EntityManager) { diff --git a/spring-orm/src/main/java/org/springframework/orm/jpa/SharedEntityManagerCreator.java b/spring-orm/src/main/java/org/springframework/orm/jpa/SharedEntityManagerCreator.java index da262d026c..cbc5e6be3d 100644 --- a/spring-orm/src/main/java/org/springframework/orm/jpa/SharedEntityManagerCreator.java +++ b/spring-orm/src/main/java/org/springframework/orm/jpa/SharedEntityManagerCreator.java @@ -355,7 +355,10 @@ public abstract class SharedEntityManagerCreator { else if (method.getName().equals("unwrap")) { // Handle JPA 2.0 unwrap method - could be a proxy match. Class targetClass = (Class) args[0]; - if (targetClass == null || targetClass.isInstance(proxy)) { + if (targetClass == null) { + return this.target; + } + else if (targetClass.isInstance(proxy)) { return proxy; } }