Hi All, I'm using the old Hibernate2(hibernate2.1.8) implementation. I'm using Single Table per Class design for my classes with the appropriate mapping and using Criteria API to generate queries using Example.create(). But the problem is the query that gets generated doesn't constrain the where clause with the fields from the subclass(which was supplied to the Example while creating a criterion. When I explicitly add an equals Expression explicitly for the subclass attribute, it gives the following exception:
va:218): net.sf.hibernate.QueryException: could not resolve property: referenceT extValue of: com.tradebeam.security.savaria.domain.object.CompanyReference at net.sf.hibernate.persister.AbstractPropertyMapping.toColumns(Abstract PropertyMapping.java:50) at net.sf.hibernate.expression.AbstractCriterion.getColumns(AbstractCrit erion.java:42) at net.sf.hibernate.expression.SimpleExpression.toSqlString(SimpleExpres sion.java:40) at net.sf.hibernate.loader.CriteriaLoader.<init>(CriteriaLoader.java:64)
at net.sf.hibernate.impl.SessionImpl.find(SessionImpl.java:3642) at net.sf.hibernate.impl.CriteriaImpl.list(CriteriaImpl.java:238) at com.tradebeam.security.savaria.domain.dao.CompanyDao.findCompanies(Co mpanyDao.java:110)
Note: 1. that this works with Hibernate 3 but doesn't work for Hibernate 2. 2. The classes using the Single table per class mappings are part of the "many" side of a one-to-many relationship. The classes are as follows public class Company{ private List<CompanyReference> companyReferences;//many side of the relationship }
public abstract class CompanyReference{ //base class fields. }
public class CompanyTextReference extends CompanyReference{ //specific fields related to company text reference } public class CompanyNumericReference extends CompanyReference{ //specific fields related to company text reference }
Here are the mappings:
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 2.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd">
<hibernate-mapping> <class name="com.tradebeam.security.savaria.domain.object.CompanyReference" table="SV_COMPANY_REFERENCES" dynamic-update="true" dynamic-insert="false" discriminator-value="0" >
<id name="companyReferenceId" column="CREF_ID" type="long" > <generator class="sequence"> <param name="sequence">COMPANY_REFERENCES_ID_S</param> </generator> </id>
<discriminator column="CREF_REFERENCE_TYPE" type="java.lang.Integer" length="1" />
<many-to-one name="company" class="com.tradebeam.security.savaria.domain.object.Company" cascade="none" outer-join="auto" update="true" insert="true" access="property" column="CREF_COMPANY_ID" not-null="true" />
<property name="referenceTypeCd" type="java.lang.Long" update="true" insert="true" access="property" column="CREF_REFERENCE_TYPE_CD" not-null="true" />
<property name="creationTimestamp" type="java.lang.Long" update="true" insert="true" access="property" column="CREF_CREATION_TIMESTAMP" />
<property name="lastUpdatedBy" type="java.lang.String" update="true" insert="true" access="property" column="CREF_LAST_UPDATED_BY" />
<property name="lastUpdateTimestamp" type="java.lang.Long" update="true" insert="true" access="property" column="CREF_LAST_UPDATE_TIMESTAMP" />
<!-- To add non XDoclet property mappings, create a file named hibernate-properties-CompanyReference.xml containing the additional properties and place it in your merge dir. --> <subclass name="com.tradebeam.security.savaria.domain.object.CompanyNumericReference" dynamic-update="true" dynamic-insert="false" discriminator-value="2" > <property name="referenceNumericValue" type="java.lang.Double" update="true" insert="true" access="property" column="CREF_NUMERIC_VALUE" />
<property name="referenceUOMCd" type="java.lang.Long" update="true" insert="true" access="property" column="CREF_UOM_CD" />
<property name="referenceUOMType" type="java.lang.Integer" update="true" insert="true" access="field" column="CREF_UOM_TYPE" />
<!-- To add non XDoclet property mappings, create a file named hibernate-properties-CompanyNumericReference.xml containing the additional properties and place it in your merge dir. -->
</subclass> <subclass name="com.tradebeam.security.savaria.domain.object.CompanyTextReference" dynamic-update="true" dynamic-insert="false" discriminator-value="1" > <property name="referenceTextValue" type="java.lang.String" update="true" insert="true" access="property" column="CREF_TEXT_VALUE" />
<!-- To add non XDoclet property mappings, create a file named hibernate-properties-CompanyTextReference.xml containing the additional properties and place it in your merge dir. -->
</subclass>
</class>
</hibernate-mapping>
Criteria is being created as follows: Criteria criteria = session.createCriteria(Company.class); //set fetch mode to lazy for associations criteria.setFetchMode("companyReferences", FetchMode.LAZY); criteria.setFetchMode("companyAddresses", FetchMode.LAZY); criteria.add(exampleCmpCriterion).addOrder(Order.asc("name")); //See if excludedCmpIdsCol is populated. If yes add a NOT IN Expression if(restrictByCmpIdsCol != null && restrictByCmpIdsCol.size() > 0) { criteria.add(Expression.in("companyID", restrictByCmpIdsCol)); } //See if excludedCmpIdsCol is populated. If yes add a NOT IN Expression if(excludedCmpIdsCol != null && excludedCmpIdsCol.size() > 0) { criteria.add(Expression.not(Expression.in("companyID", excludedCmpIdsCol))); } //Add Company ref Criterion if(expRefCriterion != null ) { criteria.createCriteria("companyReferences").add(expRefCriterion); } //Add Company Addresses Criterion if(expAdrCriterion != null) { criteria.createCriteria("companyAddresses").add(expAdrCriterion); } criteria.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);
Please provide a reason why criteria cannot detect fields of the subclass?? Is this a known bug in Hibernate 2??
|