Hello,
This problem is not specific to the new feature set of hibernate 3.0, but I am reporting this in this forum as I am using Hibernate 3.0
I have two tables Operations and Participants. From realtional point of view, Operations to particpants is one to many relationships, but participants can be of three types, Submitting Agency, Operation Contact and Other Agenceis. An operation can have exactly one submitting agency, zero or one operation contact and zero or more other agencies(enforced by business rules).
I am working on a proof of concept to convince management to use Hibernate instead of entity 2.x beans.
For now, I am trying to use one table per class hierarchy for Participants with Participant as the abstract base class and SubmittingAgency and OperationContact as its concretet subclasses. These subclasses do not have any addtional attributes or behaviours, but I am trying to model it this way just so that I can have two bidrectional (foregin key mapped) one-to-one relationships (each for submtting agency and operation contact).
I have read the book "Hibernate in action" and it mentions that we should be able to do this.
When I run the prgram, I get a WrongClassException while trying to load the OperationContact. None of the sql queries generated by Hibernate have discriminator type coulmn in the where caluse. Am I missing something in my mapping or code or could it be an unsupported feature or bug. Please refer to the mapping files, code snippets as per the given format:
Please note that Participants has Opn_ID as the foreign key column which is the primary key of Operations.
Hibernate version:hibernate-3.0_beta_1
Mapping documents:
(Relavant Sections)
Operation Class
.......
<one-to-one name="submittingAgency"
class="gov.ca.doj.sins.cev.model.SubmittingAgency"
property-ref="saToOperation"/>
<one-to-one name="operationContact"
class="gov.ca.doj.sins.cev.model.OperationContact"
property-ref="ocToOperation"/>
......
Participant, SubmittingAgency, OperationContact classes
.....
<class
name="gov.ca.doj.sins.cev.model.Participant"
table="PARTICIPANTS"
dynamic-update="true" lazy="false"
>
<id
name="id"
type="java.lang.String"
column="ID"
>
<generator class="gov.ca.doj.sins.cev.persistence.UniqueSequenceNumberFactory"/>
</id>
<discriminator
column="PARTICIPATION_TYPE_CODE"
type="string" force="true"/>
........
<subclass
name="gov.ca.doj.sins.cev.model.SubmittingAgency"
discriminator-value="SA" lazy="false">
<many-to-one name="saToOperation"
class="gov.ca.doj.sins.cev.model.Operation"
column="OPN_ID" insert="false" update="false"
cascade="all"
unique="true"/>
</subclass>
<subclass
name="gov.ca.doj.sins.cev.model.OperationContact"
discriminator-value="OC" lazy="false">
<many-to-one name="ocToOperation"
class="gov.ca.doj.sins.cev.model.Operation"
column="OPN_ID" insert="false" update="false"
cascade="all"
unique="true"/>
</subclass>
........
Code between sessionFactory.openSession() and session.close():
Service Layer
.....................
OperationDAO opnDAO = new OperationDAO();
List operations = opnDAO.getOperationsBySearchCriteria(searchParam);
HibernateUtil.closeSession();
return operations;
DAO constructor
....................
HibernateUtil.beginTransaction();
Dao
-----------
Session session = HibernateUtil.getSession();
Criteria operationCrit = session.createCriteria(Operation.class);
Criteria submittingAgencyCrit = session.createCriteria(SubmittingAgency.class);
if(searchParams.getBeginDate() != null)
{
operationCrit.add(Expression.ge("operationBeginDateTime", searchParams.getBeginDate()));
}
........
catch(HibernateException ex)
{
throw new InfrastructureException(ex);
}
Full stack trace of any exception that occurs: org.hibernate.WrongClassException: Object with id: 0000004066500101 was not of the specified subclass: gov.ca.doj.sins.cev.model.OperationContact (loaded object was of wrong class) at org.hibernate.loader.Loader.instanceAlreadyLoaded(Loader.java:707) at org.hibernate.loader.Loader.getRow(Loader.java:661) at org.hibernate.loader.Loader.getRowFromResultSet(Loader.java:278) at org.hibernate.loader.Loader.doQuery(Loader.java:366) at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:193) at org.hibernate.loader.Loader.loadEntity(Loader.java:1133) at org.hibernate.loader.EntityLoader.load(EntityLoader.java:111) at org.hibernate.loader.EntityLoader.loadByUniqueKey(EntityLoader.java:102) at org.hibernate.persister.BasicEntityPersister.loadByUniqueKey(BasicEntityPersister.java:1204) at org.hibernate.type.EntityType.loadByUniqueKey(EntityType.java:278) at org.hibernate.type.EntityType.resolve(EntityType.java:226) at org.hibernate.engine.TwoPhaseLoad.initializeEntity(TwoPhaseLoad.java:86) at org.hibernate.loader.Loader.initializeEntitiesAndCollections(Loader.java:426) at org.hibernate.loader.Loader.doQuery(Loader.java:388) at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:193) at org.hibernate.loader.Loader.doList(Loader.java:1303) at org.hibernate.loader.Loader.list(Loader.java:1286) at org.hibernate.loader.CriteriaLoader.list(CriteriaLoader.java:167) at org.hibernate.impl.SessionImpl.find(SessionImpl.java:1564) at org.hibernate.impl.CriteriaImpl.list(CriteriaImpl.java:274) at gov.ca.doj.sins.cev.dao.OperationDAO.getOperationsBySearchCriteria(OperationDAO.java:107) at gov.ca.doj.sins.cev.service.CriticalEventService.retrieveOperations(CriticalEventService.java:34) at gov.ca.doj.sins.cev.ejb.CEVSessionFacadeBean.retrieveOperations(CEVSessionFacadeBean.java:178) at CEVSessionFacade_StatelessSessionBeanWrapper0.retrieveOperations(CEVSessionFacade_StatelessSessionBeanWrapper0.java:257) at gov.ca.doj.sins.cev.struts.action.RetrieveAction.processRetrieve(RetrieveAction.java:275) at gov.ca.doj.sins.cev.struts.action.RetrieveAction.execute(RetrieveAction.java:96) at org.apache.struts.action.RequestProcessor.processActionPerform(RequestProcessor.java:480) at org.apache.struts.action.RequestProcessor.process(RequestProcessor.java:274) at org.apache.struts.action.ActionServlet.process(ActionServlet.java:1420) at org.apache.struts.action.ActionServlet.doPost(ActionServlet.java:520) at javax.servlet.http.HttpServlet.service(HttpServlet.java:760) at javax.servlet.http.HttpServlet.service(HttpServlet.java:853) at com.evermind.server.http.ResourceFilterChain.doFilter(ResourceFilterChain.java:65) at oracle.security.jazn.oc4j.JAZNFilter.doFilter(JAZNFilter.java:293) at com.evermind.server.http.ServletRequestDispatcher.invoke(ServletRequestDispatcher.java:611) at com.evermind.server.http.ServletRequestDispatcher.forwardInternal(ServletRequestDispatcher.java:317) at com.evermind.server.http.HttpRequestHandler.processRequest(HttpRequestHandler.java:782) at com.evermind.server.http.HttpRequestHandler.run(HttpRequestHandler.java:270) at com.evermind.server.http.HttpRequestHandler.run(HttpRequestHandler.java:112) at com.evermind.util.ReleasableResourcePooledExecutor$MyWorker.run(ReleasableResourcePooledExecutor.java:192) at java.lang.Thread.run(Thread.java:534)
[b]Name and version of the database you are using: oracle 9 i
[b]The generated SQL (show_sql=true):
The sql query to retrieve operation by search criteria
does a left outer join with Submitting Agency, but without
the descriminator column in the where close
The second sql query (looks klke immediate retrieve) queries Particpant
table to retrieve operation contact but without the discriminator column in the where clause.
Debug level Hibernate log excerpt:
|