I am using hibernate to do collection filtering directly on my model objects. I have come across two bugs in doing so:
1) TRUE keyword incorrectly being considered a field name
2) indirect attributes not resolved to the correct field name when outer-join="true"
The generated WHERE clause
Code:
(client.active=projects0_.TRUE)
should read
Code:
(client1_.active=TRUE)
in the SQL shown below.
Hibernate version: 3.2.4.sp1
Xdoclet generated Mapping documents:Code:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping
>
<class
name="model.Client"
table="bug_client"
>
<id
name="id"
column="id"
type="java.lang.Long"
>
<generator class="sequence">
<param name="sequence">bug_client_sequence</param>
<!--
To add non XDoclet generator parameters, create a file named
hibernate-generator-params-Client.xml
containing the additional parameters and place it in your merge dir.
-->
</generator>
</id>
<property
name="name"
type="java.lang.String"
update="true"
insert="true"
column="name"
not-null="true"
/>
<property
name="active"
type="java.lang.Boolean"
update="true"
insert="true"
column="active"
not-null="true"
/>
<set
name="projects"
lazy="true"
cascade="none"
sort="unsorted"
>
<key
column="client_id"
>
</key>
<one-to-many
class="model.Project"
/>
</set>
<!--
To add non XDoclet property mappings, create a file named
hibernate-properties-Client.xml
containing the additional properties and place it in your merge dir.
-->
</class>
</hibernate-mapping>
Code:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping
>
<class
name="model.Project"
table="bug_project"
>
<id
name="id"
column="id"
type="java.lang.Long"
>
<generator class="sequence">
<param name="sequence">bug_project_sequence</param>
<!--
To add non XDoclet generator parameters, create a file named
hibernate-generator-params-Project.xml
containing the additional parameters and place it in your merge dir.
-->
</generator>
</id>
<property
name="name"
type="java.lang.String"
update="true"
insert="true"
column="name"
not-null="true"
/>
<many-to-one
name="client"
class="model.Client"
cascade="none"
outer-join="true"
update="true"
insert="true"
column="client_id"
not-null="true"
/>
<many-to-one
name="region"
class="model.Region"
cascade="none"
outer-join="auto"
update="true"
insert="true"
column="region_id"
not-null="true"
/>
<!--
To add non XDoclet property mappings, create a file named
hibernate-properties-Project.xml
containing the additional properties and place it in your merge dir.
-->
</class>
</hibernate-mapping>
Code:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping
>
<class
name="model.Region"
table="bug_region"
>
<id
name="id"
column="id"
type="java.lang.Long"
>
<generator class="sequence">
<param name="sequence">bug_region_sequence</param>
<!--
To add non XDoclet generator parameters, create a file named
hibernate-generator-params-Region.xml
containing the additional parameters and place it in your merge dir.
-->
</generator>
</id>
<property
name="name"
type="java.lang.String"
update="true"
insert="true"
column="name"
not-null="true"
/>
<set
name="projects"
lazy="true"
cascade="none"
sort="unsorted"
where="client.active=TRUE"
>
<key
column="region_id"
>
</key>
<one-to-many
class="model.Project"
/>
</set>
<!--
To add non XDoclet property mappings, create a file named
hibernate-properties-Region.xml
containing the additional properties and place it in your merge dir.
-->
</class>
</hibernate-mapping>
Code between sessionFactory.openSession() and session.close():Code:
Region northRegion=regionDao.retrieve(new Long(1));
System.out.println("region projects.size="+northRegion.getProjects().size());
Full stack trace of any exception that occurs:Code:
[java] SEVERE: ERROR: missing FROM-clause entry for table "client"
[java] org.hibernate.exception.SQLGrammarException: could not initialize a collection: [model.Region.projects#1]
[java] at org.apache.tools.ant.taskdefs.ExecuteJava.execute(ExecuteJava.java:194)
[java] at org.apache.tools.ant.taskdefs.Java.run(Java.java:747)
[java] at org.apache.tools.ant.taskdefs.Java.executeJava(Java.java:201)
[java] at org.apache.tools.ant.taskdefs.Java.execute(Java.java:104)
[java] at org.apache.tools.ant.UnknownElement.execute(UnknownElement.java:288)
[java] at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
[java] at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
[java] at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
[java] at java.lang.reflect.Method.invoke(Method.java:597)
[java] at org.apache.tools.ant.dispatch.DispatchUtils.execute(DispatchUtils.java:105)
[java] at org.apache.tools.ant.Task.perform(Task.java:348)
[java] at org.apache.tools.ant.Target.execute(Target.java:357)
[java] at org.apache.tools.ant.Target.performTasks(Target.java:385)
[java] at org.apache.tools.ant.Project.executeSortedTargets(Project.java:1329)
[java] at org.apache.tools.ant.Project.executeTarget(Project.java:1298)
[java] at org.apache.tools.ant.helper.DefaultExecutor.executeTargets(DefaultExecutor.java:41)
[java] at org.apache.tools.ant.Project.executeTargets(Project.java:1181)
[java] at org.apache.tools.ant.Main.runBuild(Main.java:698)
[java] at org.apache.tools.ant.Main.startAnt(Main.java:199)
[java] at org.apache.tools.ant.launch.Launcher.run(Launcher.java:257)
[java] at org.apache.tools.ant.launch.Launcher.main(Launcher.java:104)
[java] Caused by: org.hibernate.exception.SQLGrammarException: could not initialize a collection: [model.Region.projects#1]
[java] at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:67)
[java] at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:43)
[java] at org.hibernate.loader.Loader.loadCollection(Loader.java:2001)
[java] at org.hibernate.loader.collection.CollectionLoader.initialize(CollectionLoader.java:36)
[java] at org.hibernate.persister.collection.AbstractCollectionPersister.initialize(AbstractCollectionPersister.java:565)
[java] at org.hibernate.event.def.DefaultInitializeCollectionEventListener.onInitializeCollection(DefaultInitializeCollectionEventListener.java:60)
[java] at org.hibernate.impl.SessionImpl.initializeCollection(SessionImpl.java:1716)
[java] at org.hibernate.collection.AbstractPersistentCollection.initialize(AbstractPersistentCollection.java:344)
[java] at org.hibernate.collection.AbstractPersistentCollection.read(AbstractPersistentCollection.java:86)
[java] at org.hibernate.collection.AbstractPersistentCollection.readSize(AbstractPersistentCollection.java:109)
[java] at org.hibernate.collection.PersistentSet.size(PersistentSet.java:139)
[java] at ref.Initialize$2.doInTransactionWithoutResult(Initialize.java:79)
[java] at org.springframework.transaction.support.TransactionCallbackWithoutResult.doInTransaction(TransactionCallbackWithoutResult.java:33)
[java] at org.springframework.transaction.support.TransactionTemplate.execute(TransactionTemplate.java:127)
[java] at ref.Initialize.main(Initialize.java:65)
[java] at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
[java] at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
[java] at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
[java] at java.lang.reflect.Method.invoke(Method.java:597)
[java] at org.apache.tools.ant.taskdefs.ExecuteJava.run(ExecuteJava.java:217)
[java] at org.apache.tools.ant.taskdefs.ExecuteJava.execute(ExecuteJava.java:152)
[java] ... 20 more
[java] Caused by: java.sql.SQLException: ERROR: missing FROM-clause entry for table "client"
[java] at org.postgresql.core.v3.QueryExecutorImpl.receiveErrorResponse(QueryExecutorImpl.java:1471)
[java] at org.postgresql.core.v3.QueryExecutorImpl.processResults(QueryExecutorImpl.java:1256)
[java] at org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:175)
[java] at org.postgresql.jdbc2.AbstractJdbc2Statement.execute(AbstractJdbc2Statement.java:389)
[java] at org.postgresql.jdbc2.AbstractJdbc2Statement.executeWithFlags(AbstractJdbc2Statement.java:330)
[java] at org.postgresql.jdbc2.AbstractJdbc2Statement.executeQuery(AbstractJdbc2Statement.java:240)
[java] at org.apache.commons.dbcp.DelegatingPreparedStatement.executeQuery(DelegatingPreparedStatement.java:205)
[java] at org.hibernate.jdbc.AbstractBatcher.getResultSet(AbstractBatcher.java:186)
[java] at org.hibernate.loader.Loader.getResultSet(Loader.java:1787)
[java] at org.hibernate.loader.Loader.doQuery(Loader.java:674)
[java] at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:236)
[java] at org.hibernate.loader.Loader.loadCollection(Loader.java:1994)
[java] ... 38 more
[java] --- Nested Exception ---
[java] org.hibernate.exception.SQLGrammarException: could not initialize a collection: [model.Region.projects#1]
[java] at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:67)
[java] at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:43)
[java] at org.hibernate.loader.Loader.loadCollection(Loader.java:2001)
[java] at org.hibernate.loader.collection.CollectionLoader.initialize(CollectionLoader.java:36)
[java] at org.hibernate.persister.collection.AbstractCollectionPersister.initialize(AbstractCollectionPersister.java:565)
[java] at org.hibernate.event.def.DefaultInitializeCollectionEventListener.onInitializeCollection(DefaultInitializeCollectionEventListener.java:60)
[java] at org.hibernate.impl.SessionImpl.initializeCollection(SessionImpl.java:1716)
[java] at org.hibernate.collection.AbstractPersistentCollection.initialize(AbstractPersistentCollection.java:344)
[java] at org.hibernate.collection.AbstractPersistentCollection.read(AbstractPersistentCollection.java:86)
[java] at org.hibernate.collection.AbstractPersistentCollection.readSize(AbstractPersistentCollection.java:109)
[java] at org.hibernate.collection.PersistentSet.size(PersistentSet.java:139)
[java] at ref.Initialize$2.doInTransactionWithoutResult(Initialize.java:79)
[java] at org.springframework.transaction.support.TransactionCallbackWithoutResult.doInTransaction(TransactionCallbackWithoutResult.java:33)
[java] at org.springframework.transaction.support.TransactionTemplate.execute(TransactionTemplate.java:127)
[java] at ref.Initialize.main(Initialize.java:65)
[java] at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
[java] at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
[java] at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
[java] at java.lang.reflect.Method.invoke(Method.java:597)
[java] at org.apache.tools.ant.taskdefs.ExecuteJava.run(ExecuteJava.java:217)
[java] at org.apache.tools.ant.taskdefs.ExecuteJava.execute(ExecuteJava.java:152)
[java] at org.apache.tools.ant.taskdefs.Java.run(Java.java:747)
[java] at org.apache.tools.ant.taskdefs.Java.executeJava(Java.java:201)
[java] at org.apache.tools.ant.taskdefs.Java.execute(Java.java:104)
[java] at org.apache.tools.ant.UnknownElement.execute(UnknownElement.java:288)
[java] at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
[java] at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
[java] at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
[java] at java.lang.reflect.Method.invoke(Method.java:597)
[java] at org.apache.tools.ant.dispatch.DispatchUtils.execute(DispatchUtils.java:105)
[java] at org.apache.tools.ant.Task.perform(Task.java:348)
[java] at org.apache.tools.ant.Target.execute(Target.java:357)
[java] at org.apache.tools.ant.Target.performTasks(Target.java:385)
[java] at org.apache.tools.ant.Project.executeSortedTargets(Project.java:1329)
[java] at org.apache.tools.ant.Project.executeTarget(Project.java:1298)
[java] at org.apache.tools.ant.helper.DefaultExecutor.executeTargets(DefaultExecutor.java:41)
[java] at org.apache.tools.ant.Project.executeTargets(Project.java:1181)
[java] at org.apache.tools.ant.Main.runBuild(Main.java:698)
[java] at org.apache.tools.ant.Main.startAnt(Main.java:199)
[java] at org.apache.tools.ant.launch.Launcher.run(Launcher.java:257)
[java] at org.apache.tools.ant.launch.Launcher.main(Launcher.java:104)
[java] Caused by: java.sql.SQLException: ERROR: missing FROM-clause entry for table "client"
[java] at org.postgresql.core.v3.QueryExecutorImpl.receiveErrorResponse(QueryExecutorImpl.java:1471)
[java] at org.postgresql.core.v3.QueryExecutorImpl.processResults(QueryExecutorImpl.java:1256)
[java] at org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:175)
[java] at org.postgresql.jdbc2.AbstractJdbc2Statement.execute(AbstractJdbc2Statement.java:389)
[java] at org.postgresql.jdbc2.AbstractJdbc2Statement.executeWithFlags(AbstractJdbc2Statement.java:330)
[java] at org.postgresql.jdbc2.AbstractJdbc2Statement.executeQuery(AbstractJdbc2Statement.java:240)
[java] at org.apache.commons.dbcp.DelegatingPreparedStatement.executeQuery(DelegatingPreparedStatement.java:205)
[java] at org.hibernate.jdbc.AbstractBatcher.getResultSet(AbstractBatcher.java:186)
[java] at org.hibernate.loader.Loader.getResultSet(Loader.java:1787)
[java] at org.hibernate.loader.Loader.doQuery(Loader.java:674)
[java] at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:236)
[java] at org.hibernate.loader.Loader.loadCollection(Loader.java:1994)
[java] ... 38 more
Name and version of the database you are using:PostgreSQL 8.2
The generated SQL (show_sql=true):Code:
[java] Hibernate: /* load one-to-many model.Region.projects */ select projects0_.region_id as region4_2_, projects0_.id as id2_, projects0_.id as id0_1_, projects0_.name as name0_1_, projects0_.client_id as client3_0_1_, projects0_.region_id as region4_0_1_, client1_.id as id1_0_, client1_.name as name1_0_, client1_.active as active1_0_ from bug_project projects0_ inner join bug_client client1_ on projects0_.client_id=client1_.id where (client.active=projects0_.TRUE) and projects0_.region_id=?