开发者

Positional Parameter with IN clause in JPA

I'm trying to evaluate the following JPQL query:

select err from Error err where err.errType = ? and err.msg in (?)

The err.msg is a relationship to an Object derived from a class called CSMessage.

So I do something like this:

...fetch my CSMessage from the DB. This part actually works...

List<CSMessage> msgList = new ArrayList<CSMessage>();
msgList.add(msg);

query.setParameter (1, new Long(0));
query.setParameter (2, msgList);

query.getResultList();

According to what I've read this should be OK. However, when I run it, I get the following stack trace:

javax.persistence.PersistenceException: org.hibernate.HibernateException: Unable to resolve entity name from Class [java.util.LinkedList] expected instance/subclass of [domain.CSMessage]
    at org.hibernate.ejb.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1235)
    at org.hibernate.ejb.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1168)
    at org.hibernate.ejb.QueryImpl.getResultList(QueryImpl.java:250)
    at dao.impl.jpa.GenericJPADaoImpl.findAllUsingQuery(GenericJPADaoImpl.java:529)
    at dao.impl.jpa.GenericJPADaoImpl.findAllUsingJPQLQuery(GenericJPADaoImpl.java:476)
    at dao.impl.jpa.ErrorDaoImpl.findAllByTypeForMessages(ErrorDaoImpl.java:72)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:79)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:618)
    at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:309)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:183)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:150)
    at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:110)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
    at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:202)
    at $Proxy36.findAllByTypeForMessages(Unknown Source)
    at dao.ErrorDaoTest.testFindAllByTypeForMessages(ErrorDaoTest.java:194)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:79)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:618)
    at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:44)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:41)
    at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20)
    at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:74)
    at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:82)
    at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:72)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:240)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:49)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:193)
    at org.junit.runners.ParentRu开发者_开发问答nner$1.schedule(ParentRunner.java:52)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:191)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:42)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:184)
    at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
    at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:236)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:180)
    at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:45)
    at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:460)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:673)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:386)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:196)
Caused by: org.hibernate.HibernateException: Unable to resolve entity name from Class [java.util.LinkedList] expected instance/subclass of [domain.CSMessage]
    at org.hibernate.tuple.entity.PojoEntityTuplizer.determineConcreteSubclassEntityName(PojoEntityTuplizer.java:362)
    at org.hibernate.persister.entity.AbstractEntityPersister.getSubclassEntityPersister(AbstractEntityPersister.java:3918)
    at org.hibernate.impl.SessionImpl.getEntityPersister(SessionImpl.java:1484)
    at org.hibernate.engine.ForeignKeys.isTransient(ForeignKeys.java:203)
    at org.hibernate.engine.ForeignKeys.getEntityIdentifierIfNotUnsaved(ForeignKeys.java:243)
    at org.hibernate.type.EntityType.getIdentifier(EntityType.java:449)
    at org.hibernate.type.ManyToOneType.nullSafeSet(ManyToOneType.java:142)
    at org.hibernate.param.PositionalParameterSpecification.bind(PositionalParameterSpecification.java:68)
    at org.hibernate.loader.hql.QueryLoader.bindParameterValues(QueryLoader.java:571)
    at org.hibernate.loader.Loader.prepareQueryStatement(Loader.java:1632)
    at org.hibernate.loader.Loader.doQuery(Loader.java:717)
    at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:270)
    at org.hibernate.loader.Loader.doList(Loader.java:2449)
    at org.hibernate.loader.Loader.listIgnoreQueryCache(Loader.java:2192)
    at org.hibernate.loader.Loader.list(Loader.java:2187)
    at org.hibernate.loader.hql.QueryLoader.list(QueryLoader.java:452)
    at org.hibernate.hql.ast.QueryTranslatorImpl.list(QueryTranslatorImpl.java:363)
    at org.hibernate.engine.query.HQLQueryPlan.performList(HQLQueryPlan.java:196)
    at org.hibernate.impl.SessionImpl.list(SessionImpl.java:1258)
    at org.hibernate.impl.QueryImpl.list(QueryImpl.java:102)
    at org.hibernate.ejb.QueryImpl.getResultList(QueryImpl.java:241)
    ... 43 more

I'm confused. Anyone have a clue what I'm doing wrong?

Thanks...


Ok, so this was simply a bone-headed mistake on my part. I've been using Hibernate's query language for a while, and when I moved to JPA, I missed the fact that positional parameters are different in JPA.

Where a positional parameter in Hibernate only uses the '?' by itself, JPA wants to be able to reuse positional parameters, so the parameter should look like '?#' where # is any number greater than 1.

It seems that if you forget these numbers, JPA tries to do something, and in most cases it works just fine, but when trying to pass a list as a positional parameter, it fails. It seems to me that the query parser should throw an exception when parsing the query, if the positional parameters are wrong, but it doesn't appear to do so.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜