2010-10-13 6 views
2

Je suis en train d'évaluer la requête JPQL suivante:positionnel Paramètre avec clause IN dans JPA

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

Le err.msg est une relation à un objet dérivé d'une classe appelée CSMessage.

donc je fais quelque chose comme ceci:

...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(); 

D'après ce que j'ai lu cela devrait être OK. Toutefois, lorsque je l'exécute, j'obtiens la trace de pile suivante:

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.ParentRunner$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 

Je suis confus. Quelqu'un at-il une idée de ce que je fais mal?

Merci ...

Répondre

1

Ok, donc ce fut tout simplement une erreur à tête d'os de ma part. J'utilise le langage de requêtes d'Hibernate depuis un moment, et quand je suis passé en JPA, j'ai manqué le fait que les paramètres de position soient différents dans JPA.

Lorsqu'un paramètre de position dans Hibernate utilise uniquement le '?' JPA veut être en mesure de réutiliser les paramètres positionnels, donc le paramètre devrait ressembler à "? #" où # est un nombre supérieur à 1.

Il semble que si vous oubliez ces chiffres, JPA essaie de faire quelque chose et, dans la plupart des cas, cela fonctionne très bien, mais en essayant de passer une liste en paramètre de position, cela échoue. Il me semble que l'analyseur de requête devrait lancer une exception lors de l'analyse de la requête, si les paramètres de position sont erronés, mais cela ne semble pas le cas.