New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Spring 3.0 ORM with JPA 2.0 TypedQuery ClassCastException [SPR-6733] #11399
Comments
Juergen Hoeller commented Good point! I've revised the query proxying code to determine all interfaces implemented by the target Query object which includes the JPA 2.0 TypedQuery interface and also query vendor interfaces. This should be available in tonight's 3.0.1 snapshot already. Feel free to give it an early try... Juergen |
Daniel Kvasnička commented I've encountered this issue as well, using GlassFish v3 and its built-in JPA implementation (EclipseLink I believe). I am using Spring 3.0.1.RELEASE-A. TypedQuery<Test> query = em.createQuery("SELECT t FROM Test t;", Test.class); produces java.lang.ClassCastException: $Proxy111 cannot be cast to javax.persistence.TypedQuery |
Juergen Hoeller commented Daniel, I can't reproduce this: TypedQuery access against a shared EntityManager works for me. Could you please provide some details on where your "em" reference comes from? It would also be great if you could debug into the proxy's InvocationHandler a bit: Line 244 of SharedEntityManagerCreator is where the Query proxy is being built, using the interfaces of the target Query object for the proxy as well. Juergen |
Daniel Kvasnička commented Hi, I managed to get rid of the error by changing my setup a bit. I am now using org.springframework.orm.jpa.support.JpaDaoSupport as a superclass for my DAO instead of my own generic DAO ancestor, which did the trick and greatly simplified my JPA-related code. The em instance was from that base DAO of mine (an abstract Spring bean) and it was injected by Spring thanks to My PU definition in persistence.xml: <persistence-unit name="pu" transaction-type="JTA">
</persistence-unit> Maybe the ultra-concise JNDI-only JPA config is the problem. When I had this:
everything worked like a charm. |
Juergen Hoeller commented I have a suspicion that the JNDI-obtained EntityManagerFactory from GlassFish has some special ClassLoader arrangement behind it. I've revised Spring's SharedEntityManagerCreator a bit so that it extracts interfaces using the target factory's actual ClassLoader, instead of the JPA API ClassLoader as it did before in such a case. This might solve your original issue. Juergen |
Shashi Kale commented Hi, I am using 3.0.1.RELEASE-A of spring along with Spring DM and am facing a similar issue. Query q = em.createQuery("SELECT e FROM " + entityClazz.getSimpleName()
I get Caused by: java.lang.ClassCastException: $Proxy194 cannot be cast to javax.persistence.Query Daniel's solution wouldn't work for me since I can't discard my generic DAO implementation. Hi Juergen, Thanks and Regards, |
Shashi Kale commented Hi Again, Missed to mention that if I make the method in my DAO transactional it works all fine. It doesn't work only if I make it non transactional. Thanks, |
Ke CAI opened SPR-6733 and commented
see: http://stackoverflow.com/questions/2101500/spring-3-0-orm-with-jpa-2-0-classcastexception/2102328#2102328
I'm trying to use JPA 2.0 in Spring 3.0 ORM. The JPA vendor is Hibernate 3.5.0-Beta-3.
It works well with JPQL, but when I tried to use CriteriaQuery, an exception happens:
java.lang.ClassCastException: $Proxy50 cannot be cast to javax.persistence.TypedQuery at $Proxy38.createQuery(Unknown Source) at com.absorbx.retailx.dao.impl.ShopDaoImpl.findByCrieria(ShopDaoImpl.java:30) at com.absorbx.retailx.dao.SimpleDaoTest.testFindByCriteria(SimpleDaoTest.java:39) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
The DAO code:
@Repository
public class ShopDaoImpl implements
ShopDao {
@PersistenceContext
transient EntityManager entityManager;
}
It seems to be a bug in Spring:
org/springframework/orm/jpa/SharedEntityManagerCreator.java:
if (result instanceof Query) {
Query query = (Query) result;
...
result = Proxy.newProxyInstance(Query.class.getClassLoader(),
new Class[] {Query.class}, new DeferredQueryInvocationHandler(query, target));
...
}
Good catch. Spring is checking to see if the query is an instance of Query, and generates the proxy of that type. Unfortunately, TypedQuery is a subtype of Query, and the generated proxy will still only implement Query. TypedQuery was introduced in JavaEE 6, so it's understandable why Spring doesn't handle it, although Spring 3 is supposed to handle JavaEE 6 properly. Definitely a bug.
Affects: 3.0 GA
Reference URL: http://stackoverflow.com/questions/2101500/spring-3-0-orm-with-jpa-2-0-classcastexception/2102328#2102328
Issue Links:
Referenced from: commits bcfef8a, 0aee6e9
2 votes, 3 watchers
The text was updated successfully, but these errors were encountered: