I am trying to write an hql query that uses subselects and dereferences a map collection.
When I write
Code:
List patients=sess.find("select p.head " +
" from IDNSNode as p where p.values['age'].int_value<30");
everything is fine. However I need to use subselects to achieve what i want to do, and
the simplest example is of the form:
Code:
List patients=sess.find("select distinct n.head from IDNSNode as n " +
"where n.head in " +
" (select p.head " +
" from IDNSNode as p where p.values['age'].int_value<30)");
Where the 'values' map is a collection of entities that may be of several different subclasses as defined in the mapping files given below.
I downloaded the v22branch since this copes with the polymorphism necessary to continue the path expression (ie values['age'].int_value) BUT does not work with subselects. I am using postgres 7.4.1 which supports subqueries and if I rewrite the queries not using the
'values['age'].int_value style notation they work.
The second example above results in the following exception:
Code:
Exception in thread "main" net.sf.hibernate.QueryException: unexpected [ [select distinct n.head from myapp.IDNSNode as n where n.head in (select p.head from myapp.IDNSNode as p where p.values['age'].int_value<30)]
at net.sf.hibernate.hql.WhereParser.token(WhereParser.java:185)
at net.sf.hibernate.hql.ClauseParser.token(ClauseParser.java:87)
at net.sf.hibernate.hql.PreprocessingParser.token(PreprocessingParser.java:123)
at net.sf.hibernate.hql.ParserHelper.parse(ParserHelper.java:29)
at net.sf.hibernate.hql.QueryTranslatorImpl.compile(QueryTranslatorImpl.java:163)
at net.sf.hibernate.hql.QueryTranslatorImpl.compile(QueryTranslatorImpl.java:138)
at net.sf.hibernate.impl.SessionFactoryImpl.getQuery(SessionFactoryImpl.java:318)
at net.sf.hibernate.impl.SessionImpl.getQueries(SessionImpl.java:1086)
at net.sf.hibernate.impl.SessionImpl.find(SessionImpl.java:1057)
at net.sf.hibernate.impl.SessionImpl.find(SessionImpl.java:1046)
at net.sf.hibernate.impl.SessionImpl.find(SessionImpl.java:1038)
at myapp.Test.findData(Test.java:189)
at myapp.Test.main(Test.java:228)
Process terminated with exit code 1
I can sidestep the problem using a different formulation of hql but life would be simpler if
I could use the above style query.
Mapping files follow:
<hibernate-mapping default-cascade="save-update">
<class name="myapp.IDNSNode"
table="rdef">
<id name="id" type="integer"
unsaved-value="0">
<column name="id" sql-type="integer"
not-null="true"/>
<generator class="increment"/>
</id>
<property name="name">
<column name="name" sql-type="varchar(20)"
not-null="true"/>
</property>
<many-to-one name="head" class="myapp.IDNSNode" cascade="all" >
<column name="head_id" sql-type="integer"/>
</many-to-one>
<many-to-one name="parent" class="myapp.IDNSNode" cascade="all">
<column name="parent_id" sql-type="integer"/>
</many-to-one>
<set name="children" table="rdef" inverse="true" lazy="true">
<key column="parent_id"/>
<one-to-many class="myapp.IDNSNode" />
</set>
<map name="values" table="values" inverse="true" lazy="true">
<key column="parent_id"/>
<index column="name" type="string"/>
<one-to-many class="myapp.IDNSValue" />
</map>
<set name="datasets" table="nodes" lazy="true">
<key column="node_id"/>
<many-to-many column="dataset_id" class="myapp.DataSet"/>
</set>
</class>
</hibernate-mapping>
And for the values:
<hibernate-mapping default-cascade="save-update">
<class name="myapp.IDNSValue" table="values" discriminator-value="Value">
<id name="id" type="integer"
unsaved-value="0">
<column name="id" sql-type="integer"
not-null="true"/>
<generator class="increment"/>
</id>
<discriminator column="class" />
<property name="name">
<column name="name" sql-type="varchar(20)"
not-null="true"/>
</property>
<many-to-one name="parent" class="myapp.IDNSNode">
<column name="parent_id" sql-type="integer"/>
</many-to-one>
<many-to-one name="head" class="myapp.IDNSNode" >
<column name="head_id" sql-type="integer"/>
</many-to-one>
<subclass name="myapp.IDNSStringValue" discriminator-value="StringValue">
<property name="string_value" type="string" >
<column name="string_value" sql-type="text"/>
</property>
</subclass>
<subclass name="myapp.IDNSIntValue" discriminator-value="IntValue">
<property name="int_value" type="integer" >
<column name="int_value" sql-type="integer"/>
</property>
</subclass>
</class>
</hibernate-mapping>