I am having trouble using Restrictions.isNotEmpty(collectionPropertyName) when the collection is defined in a super class.
Looking at the code, the CollectionPersister is stored using the superclass name, in this case "test.subclass.collections.
Person.races"
But when the SQL is being generated for the Criterion, the role passed into the SessionFactoryImpl.getCollectionPersister(String role) method, the role it is looking for is "test.subclass.collections.
Client.races" presumeably since the Criteria was created for the Client.class.
Is this a bug ?
Hibernate version:
3.0.2
Mapping documents:
Code:
<hibernate-mapping package="test.subclass.collections">
<class name="Person" table="PRSN" discriminator-value="0">
<id column="PRSN_ID" name="personId" type="java.lang.Long">
<generator class="native" />
</id>
<discriminator column="PRSN_TP_ID" not-null="true" type="java.lang.Long"/>
<property name="personName" column="PERSON_NAME" type="java.lang.String" />
<set name="races" table="PRSN_RACE" inverse="true" cascade="all,delete-orphan">
<key column="PRSN_ID" />
<one-to-many class="PersonRace" />
</set>
</class>
</hibernate-mapping>
<hibernate-mapping package="test.subclass.collections">
<subclass name="Client" extends="test.subclass.collections.Person" discriminator-value="1" />
</hibernate-mapping>
<hibernate-mapping package="test.subclass.collections">
<class name="PersonRace" table="PRSN_RACE">
<id column="PRSN_RACE_ID" name="personRaceId" type="java.lang.Long">
<generator class="native"/>
</id>
<many-to-one column="PRSN_ID" name="person" class="Person" not-null="true" embed-xml="false" />
<property column="RACE_ID" name="raceId" />
</class>
</hibernate-mapping>
<hibernate-mapping package="test.subclass.collections">
<class name="Race" table="RACE">
<id column="RACE_ID" name="id" type="java.lang.Long">
<generator class="assigned"/>
</id>
<property column="DSCRPTR" name="descriptor" type="java.lang.String"/>
</class>
</hibernate-mapping>
Code between sessionFactory.openSession() and session.close():Code:
Transaction trans = session.beginTransaction();
//Create Race reference data
Race race1 = new Race(new Long(100), "White");
session.save(race1);
Race race2 = new Race(new Long(200), "Asian");
session.save(race2);
// Create a Client object containing two races.
Client client = new Client();
client.setPersonName("Test Person 1");
client.addPersonRace(race1);
client.addPersonRace(race2);
session.save(client);
trans.commit();
Collection results = session.createCriteria(Client.class)
.add(Restrictions.isNotEmpty("races")).list();
Full stack trace of any exception that occurs:
org.hibernate.MappingException: Unknown collection role: test.subclass.collections.Client.races
at org.hibernate.impl.SessionFactoryImpl.getCollectionPersister(SessionFactoryImpl.java:561)
at org.hibernate.criterion.NotEmptyExpression.toSqlString(NotEmptyExpression.java:36)
at org.hibernate.loader.criteria.CriteriaQueryTranslator.getWhereCondition(CriteriaQueryTranslator.java:313)
at org.hibernate.loader.criteria.CriteriaLoader.<init>(CriteriaLoader.java:94)
at org.hibernate.impl.SessionImpl.list(SessionImpl.java:1236)
at org.hibernate.impl.CriteriaImpl.list(CriteriaImpl.java:299)
at test.subclass.collections.TestRestrictionsIsNotEmpty.testRestrictionsIsNotEmpty(TestRestrictionsIsNotEmpty.java:23)
at test.subclass.collections.TestRestrictionsIsNotEmpty.main(TestRestrictionsIsNotEmpty.java:16)
Name and version of the database you are using:
HSQLDB 1.7.2
The generated SQL (show_sql=true):
Failure occurs during SQL Generation
Debug level Hibernate log excerpt:
2005-05-02 16:54:40,750 1922 DEBUG [org.hibernate.transaction.JDBCTransaction] (main:) committed JDBC Connection
2005-05-02 16:54:40,750 1922 DEBUG [org.hibernate.jdbc.JDBCContext] (main:) after transaction completion
2005-05-02 16:54:40,750 1922 DEBUG [org.hibernate.impl.SessionImpl] (main:) after transaction completion
2005-05-02 16:54:40,750 1922 DEBUG [org.hibernate.impl.SessionImpl] (main:) opened session at timestamp: 4567315581952000
org.hibernate.MappingException: Unknown collection role: test.subclass.collections.Client.races
at org.hibernate.impl.SessionFactoryImpl.getCollectionPersister(SessionFactoryImpl.java:561)
at org.hibernate.criterion.NotEmptyExpression.toSqlString(NotEmptyExpression.java:36)
at org.hibernate.loader.criteria.CriteriaQueryTranslator.getWhereCondition(CriteriaQueryTranslator.java:313)
at org.hibernate.loader.criteria.CriteriaLoader.<init>(CriteriaLoader.java:94)
at org.hibernate.impl.SessionImpl.list(SessionImpl.java:1236)
at org.hibernate.impl.CriteriaImpl.list(CriteriaImpl.java:299)
at test.subclass.collections.TestRestrictionsIsNotEmpty.testRestrictionsIsNotEmpty(TestRestrictionsIsNotEmpty.java:23)
at test.subclass.collections.TestRestrictionsIsNotEmpty.main(TestRestrictionsIsNotEmpty.java:16)
2005-05-02 16:54:40,828 2000 DEBUG [org.hibernate.jdbc.JDBCContext] (Secondary finalizer:) running Session.finalize()
2005-05-02 16:54:40,828 2000 DEBUG [org.hibernate.jdbc.JDBCContext] (Secondary finalizer:) running Session.finalize()
2005-05-02 16:54:40,828 2000 WARN [org.hibernate.jdbc.JDBCContext] (Secondary finalizer:) unclosed connection, forgot to call close() on your session?
2005-05-02 16:54:40,937 2109 INFO [org.hibernate.connection.DriverManagerConnectionProvider] (Secondary finalizer:) cleaning up connection pool: jdbc:hsqldb:C:\hsql\testx
Exception in thread "main"