[hibernate-issues] [Hibernate-JIRA] Commented: (HHH-5396) JPQL KEY() and VALUE() not implemented

Yannick Lazzari (JIRA) noreply at atlassian.com
Wed May 9 11:29:12 EDT 2012


    [ https://hibernate.onjira.com/browse/HHH-5396?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=46579#comment-46579 ] 

Yannick Lazzari commented on HHH-5396:
--------------------------------------

Any update on the progress of that one?  As of version 4.1.2.Final, nothing has changed.  Using the keyword in upper case (e.g. 'KEY(t)') just passes through to the SQL statement and obviously the RDBMS complains (Oracle in my case).  When using the keyword in lower case, I get the following stacktrace.  In the meantime, the only solution I found to query the relations properly is to refrain from using Map relations, simply use other collections and add utility methods to manipulate the collections as Maps when needed.  Works, but the Map collection is elegant and useful sometimes, especially for multi-lingual patterns (exactly the one described in the bug report).

Caused by: org.hibernate.hql.internal.ast.QuerySyntaxException: unexpected AST node:  [from Order t inner join t.details t2 where key(t2) = 'EN' order by t2.title]
	at org.hibernate.hql.internal.ast.QuerySyntaxException.convert(QuerySyntaxException.java:54) ~[hibernate-core-4.1.2.Final.jar:4.1.2.Final]
	at org.hibernate.hql.internal.ast.QuerySyntaxException.convert(QuerySyntaxException.java:47) ~[hibernate-core-4.1.2.Final.jar:4.1.2.Final]
	at org.hibernate.hql.internal.ast.ErrorCounter.throwQueryException(ErrorCounter.java:79) ~[hibernate-core-4.1.2.Final.jar:4.1.2.Final]
	at org.hibernate.hql.internal.ast.QueryTranslatorImpl.analyze(QueryTranslatorImpl.java:255) ~[hibernate-core-4.1.2.Final.jar:4.1.2.Final]
	at org.hibernate.hql.internal.ast.QueryTranslatorImpl.doCompile(QueryTranslatorImpl.java:183) ~[hibernate-core-4.1.2.Final.jar:4.1.2.Final]
	at org.hibernate.hql.internal.ast.QueryTranslatorImpl.compile(QueryTranslatorImpl.java:136) ~[hibernate-core-4.1.2.Final.jar:4.1.2.Final]
	at org.hibernate.engine.query.spi.HQLQueryPlan.<init>(HQLQueryPlan.java:105) ~[hibernate-core-4.1.2.Final.jar:4.1.2.Final]
	at org.hibernate.engine.query.spi.HQLQueryPlan.<init>(HQLQueryPlan.java:80) ~[hibernate-core-4.1.2.Final.jar:4.1.2.Final]
	at org.hibernate.engine.query.spi.QueryPlanCache.getHQLQueryPlan(QueryPlanCache.java:168) ~[hibernate-core-4.1.2.Final.jar:4.1.2.Final]
	at org.hibernate.internal.AbstractSessionImpl.getHQLQueryPlan(AbstractSessionImpl.java:216) ~[hibernate-core-4.1.2.Final.jar:4.1.2.Final]
	at org.hibernate.internal.AbstractSessionImpl.createQuery(AbstractSessionImpl.java:194) ~[hibernate-core-4.1.2.Final.jar:4.1.2.Final]
	at org.hibernate.internal.SessionImpl.createQuery(SessionImpl.java:1703) ~[hibernate-core-4.1.2.Final.jar:4.1.2.Final]
	at org.hibernate.ejb.AbstractEntityManagerImpl.createQuery(AbstractEntityManagerImpl.java:286) ~[hibernate-entitymanager-4.1.2.Final.jar:4.1.2.Final]

> JPQL KEY() and VALUE() not implemented
> --------------------------------------
>
>                 Key: HHH-5396
>                 URL: https://hibernate.onjira.com/browse/HHH-5396
>             Project: Hibernate ORM
>          Issue Type: Bug
>    Affects Versions: 3.5.3
>         Environment: Hibernate 3.5.3, PostgreSQL 8.4.3
>            Reporter: Harald Wellmann
>
> The KEY() and VALUE() operators for persistent maps do not seem to be implemented in Hibernate.
> E.g. consider the query
> {code}
> select m.text from MultilingualString s join s.map m where key(m) = 'de'
> {code}
> given the following classes and mappings.
> {code:java}
> @Embeddable
> public class LocalizedString {
>     private String language;
>     @Column(name = "_text")
>     private String text;
> }
> @Entity
> @Table(schema = "jpa", name = "multilingual_string")
> public class MultilingualString {
>     @Id
>     @GeneratedValue(strategy = GenerationType.SEQUENCE)
>     @Column(name = "string_id")
>     private long id;
>     @ElementCollection(fetch=FetchType.EAGER)
>     @MapKeyColumn(name = "language_key", insertable = false, updatable = false)
>     @CollectionTable(schema = "jpa", name = "multilingual_string_map", joinColumns = @JoinColumn(name = "string_id"))
>     private Map<String, LocalizedString> map = new HashMap<String, LocalizedString>();
> }
> {code}
> (Note that these mappings are similar to but slightly different from the ones I used in HHH-5393. This time the map key column has a different name, creating a redundant column I would have liked to avoid. That way, Hibernate is at least happy about the mapping.)
> Running the query, I get the following exception:
> java.lang.IllegalArgumentException: org.hibernate.hql.ast.QuerySyntaxException: unexpected AST node:  [select m.text from de.myjourney.model.media.MultilingualString s join s.map m where key(m) = 'de']
> 	at org.hibernate.ejb.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1222)
> 	at org.hibernate.ejb.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1168)
> 	at org.hibernate.ejb.AbstractEntityManagerImpl.createQuery(AbstractEntityManagerImpl.java:292)
> 	at de.myjourney.model.test.MultilingualStringTest.createGerman(MultilingualStringTest.java:35)
> 	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
> 	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
> 	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
> 	at java.lang.reflect.Method.invoke(Method.java:597)
> 	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.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:76)
> 	at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50)
> 	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.junit.runners.ParentRunner.run(ParentRunner.java:236)
> 	at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:46)
> 	at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
> 	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
> 	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
> 	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
> 	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)
> Caused by: org.hibernate.hql.ast.QuerySyntaxException: unexpected AST node:  [select m.text from de.myjourney.model.media.MultilingualString s join s.map m where key(m) = 'de']
> 	at org.hibernate.hql.ast.QuerySyntaxException.convert(QuerySyntaxException.java:54)
> 	at org.hibernate.hql.ast.QuerySyntaxException.convert(QuerySyntaxException.java:47)
> 	at org.hibernate.hql.ast.ErrorCounter.throwQueryException(ErrorCounter.java:82)
> 	at org.hibernate.hql.ast.QueryTranslatorImpl.analyze(QueryTranslatorImpl.java:261)
> 	at org.hibernate.hql.ast.QueryTranslatorImpl.doCompile(QueryTranslatorImpl.java:185)
> 	at org.hibernate.hql.ast.QueryTranslatorImpl.compile(QueryTranslatorImpl.java:136)
> 	at org.hibernate.engine.query.HQLQueryPlan.<init>(HQLQueryPlan.java:101)
> 	at org.hibernate.engine.query.HQLQueryPlan.<init>(HQLQueryPlan.java:80)
> 	at org.hibernate.engine.query.QueryPlanCache.getHQLQueryPlan(QueryPlanCache.java:98)
> 	at org.hibernate.impl.AbstractSessionImpl.getHQLQueryPlan(AbstractSessionImpl.java:156)
> 	at org.hibernate.impl.AbstractSessionImpl.createQuery(AbstractSessionImpl.java:135)
> 	at org.hibernate.impl.SessionImpl.createQuery(SessionImpl.java:1760)
> 	at org.hibernate.ejb.AbstractEntityManagerImpl.createQuery(AbstractEntityManagerImpl.java:277)
> 	... 23 more
> Using upper-case 'KEY(m)', the exception is different:
> javax.persistence.PersistenceException: org.hibernate.exception.SQLGrammarException: could not execute query
> 	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 de.myjourney.model.test.MultilingualStringTest.createGerman(MultilingualStringTest.java:36)
> 	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
> 	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
> 	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
> 	at java.lang.reflect.Method.invoke(Method.java:597)
> 	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.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:76)
> 	at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50)
> 	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.junit.runners.ParentRunner.run(ParentRunner.java:236)
> 	at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:46)
> 	at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
> 	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
> 	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
> 	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
> 	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)
> Caused by: org.hibernate.exception.SQLGrammarException: could not execute query
> 	at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:92)
> 	at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:66)
> 	at org.hibernate.loader.Loader.doList(Loader.java:2297)
> 	at org.hibernate.loader.Loader.listIgnoreQueryCache(Loader.java:2172)
> 	at org.hibernate.loader.Loader.list(Loader.java:2167)
> 	at org.hibernate.loader.hql.QueryLoader.list(QueryLoader.java:448)
> 	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)
> 	... 23 more
> Caused by: org.postgresql.util.PSQLException: FEHLER: Funktion key(bigint) existiert nicht
>   Hint: Keine Funktion stimmt mit dem angegebenen Namen und den Argumenttypen überein. Sie müssen möglicherweise ausdrückliche Typumwandlungen hinzufügen.
>   Position: 161
> 	at org.postgresql.core.v3.QueryExecutorImpl.receiveErrorResponse(QueryExecutorImpl.java:2062)
> 	at org.postgresql.core.v3.QueryExecutorImpl.processResults(QueryExecutorImpl.java:1795)
> 	at org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:257)
> 	at org.postgresql.jdbc2.AbstractJdbc2Statement.execute(AbstractJdbc2Statement.java:479)
> 	at org.postgresql.jdbc2.AbstractJdbc2Statement.executeWithFlags(AbstractJdbc2Statement.java:367)
> 	at org.postgresql.jdbc2.AbstractJdbc2Statement.executeQuery(AbstractJdbc2Statement.java:271)
> 	at org.hibernate.jdbc.AbstractBatcher.getResultSet(AbstractBatcher.java:208)
> 	at org.hibernate.loader.Loader.getResultSet(Loader.java:1849)
> 	at org.hibernate.loader.Loader.doQuery(Loader.java:718)
> 	at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:270)
> 	at org.hibernate.loader.Loader.doList(Loader.java:2294)
> 	... 31 more
> (The message from PostgreSQL means "Function key(bigint) does not exist".)
> I had a look at the ANTLR grammar for the query parser a while ago (which may have been before 3.5.3), and as far as I could make out, key() and value() are only recognized as lower case keywords, and while the parser accepts the syntax, it fails to generate any appropriate actions.
> The stack traces are up-to-date though, I just ran my test cases on Hibernate 3.5.3.

--
This message is automatically generated by JIRA.
For more information on JIRA, see: http://www.atlassian.com/software/jira

       



More information about the hibernate-issues mailing list