-->
These old forums are deprecated now and set to read-only. We are waiting for you on our new forums!
More modern, Discourse-based and with GitHub/Google/Twitter authentication built-in.

All times are UTC - 5 hours [ DST ]



Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 2 posts ] 
Author Message
 Post subject: Indiscriminate query problem
PostPosted: Wed Jun 29, 2005 3:14 pm 
Newbie

Joined: Wed Jun 29, 2005 2:39 pm
Posts: 2
Location: Chapel Hill, NC
Hello I've run into a snag. It's not clear to me if it's a problem with Hibernate or a problem with the way I'm using it. Essentially Hibernate is not using the discriminator where I would expect it to.

Vital stats:
Hibernate Version 2.1.8
DB: Oracle 9 (thin driver)

Here is the mapping for our Test type. Test is abstract with two contrete subclasses, CrossCheckTest and UniquenessConstraint:

<class name="form.Test" table="TEST_TABLE">
<id name="id" type="long">
<generator class="native"/>
</id>
<discriminator column="type" type="string" not-null="true"/>
<property name="required" type="boolean" not-null="true"/>
<subclass name="com.rhoworld.edc.model.form.CrossCheckTest" discriminator-value="C">
<property name="name" type="string"/>
<many-to-one name="event" class="base.DataEvent" column="event_id"/>
</subclass>
<subclass name="base.RealDataEvent$UniquenessConstraint" discriminator-value="U">
<many-to-one name="event" class="base.RealDataEvent" column="event_id" not-null="true"/>
<property name="label" type="string"/>
<property name="strict" type="boolean"/>
<set name="ifields" table="UNIQUE_TEST_IFIELDS_TABLE" lazy="false">
<key column="uniqueness_constraint_id"/>
<many-to-many class="form.IField" column="ifield_id"/>
</set>
</subclass>
</class>

Both types of tests can be children of RealDataEvent, defined here:

<class name="base.Event" table="EVENT_TABLE">
<id name="id" type="long">
<generator class="native"/>
</id>
<discriminator column="type" type="string" not-null="true"/>
<property name="name" type="string" not-null="true"/>
<subclass name="base.DataEvent">
<property name="createLabel" type="string"/>
<subclass name="base.VirtualDataEvent" discriminator-value="V">
<many-to-one name="realEvent" class="base.RealDataEvent" column="real_event_id"/>
</subclass>
<subclass name="base.RealDataEvent" discriminator-value="D">
<property name="label" type="string"/>
<map name="crossCheckTests" inverse="true" lazy="true" cascade="all-delete-orphan" order-by="offset, name">
<key column="event_id"/>
<index column="name" type="string"/>
<one-to-many class="form.CrossCheckTest"/>
</map>
<set name="uniquenessConstraints" inverse="true" lazy="true" cascade="all-delete-orphan">
<key column="event_id"/>
<one-to-many class="base.RealDataEvent$UniquenessConstraint"/>
</set>
</subclass>
</subclass>
</class>

(Many irrelevant properties have been removed in order to focus on critical bits in above mapping doc.)

A call to RealDataEvent.getCrossCheckTests() generates the following SQL (whitespace added for readability):

select crosscheck0_.event_id as event_id__,
crosscheck0_.id as id__,
crosscheck0_.name as name__,
crosscheck0_.id as id0_,
crosscheck0_.expr as expr0_,
crosscheck0_.error as error0_,
crosscheck0_.contextPath as contextP8_0_,
crosscheck0_.name as name0_,
crosscheck0_.offset as offset0_,
crosscheck0_.event_id as event_id0_,
crosscheck0_.required as required0_
from TEST_TABLE crosscheck0_
where crosscheck0_.event_id=?
order by crosscheck0_.offset, crosscheck0_.name

I have determined that the reason my code is breaking is this query is returning both UniquenessConstraints and CrossCheckTests. I'm somewhat surprised looking at the "where" clause since I would have epxected for the discriminator to be there, ie:

where crosscheck0_.event_id=? and crosscheck0_.type='C'

I'm fairly certain including the discriminator in the query would fix my woes. Is there some reason why this isn't discriminating in the way I expect. Have I done something wrong in my mapping document?

Thanks for your help. Included below is a stack trace illustrating where my code breaks, although I'm pretty sure above is the culprit.

Thank you for your help,
Chris

15:02:29,640 ERROR net.sf.hibernate.collection.PersistentCollection:198 - Failed
to lazily initialize a collection
net.sf.hibernate.HibernateException: null index column for collection: com.rhowo
rld.edc.model.base.RealDataEvent.crossCheckTests
at net.sf.hibernate.collection.AbstractCollectionPersister.readIndex(Abs
tractCollectionPersister.java:368)
at net.sf.hibernate.collection.Map.readFrom(Map.java:201)
at net.sf.hibernate.loader.Loader.readCollectionElement(Loader.java:380)
at net.sf.hibernate.loader.Loader.getRowFromResultSet(Loader.java:235)
at net.sf.hibernate.loader.Loader.doQuery(Loader.java:281)
at net.sf.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections
(Loader.java:133)
at net.sf.hibernate.loader.Loader.loadCollection(Loader.java:990)
at net.sf.hibernate.loader.Loader.loadCollection(Loader.java:965)
at net.sf.hibernate.loader.OneToManyLoader.initialize(OneToManyLoader.ja
va:93)
at net.sf.hibernate.collection.AbstractCollectionPersister.initialize(Ab
stractCollectionPersister.java:284)
at net.sf.hibernate.impl.SessionImpl.initializeCollection(SessionImpl.ja
va:3268)
at net.sf.hibernate.collection.PersistentCollection.initialize(Persisten
tCollection.java:195)
at net.sf.hibernate.collection.PersistentCollection.read(PersistentColle
ction.java:71)
at net.sf.hibernate.collection.Map.entrySet(Map.java:174)
at com.rhoworld.edc.controller.request.editor.PanelUpdater.applyCrossChe
cksTests(PanelUpdater.java:278)


Top
 Profile  
 
 Post subject:
PostPosted: Wed Jun 29, 2005 4:51 pm 
Newbie

Joined: Wed Jun 29, 2005 2:39 pm
Posts: 2
Location: Chapel Hill, NC
While I would still love to see a reply to the message above, I did want to share the work around I figured out to get around this, which is basically to use the key column names as discriminators. In other words:

<class name="form.Test">
<subclass name="form.CrossCheckTest">
<many-to-one name="event" class="base.RealDataEvent" column="event_id_C"/>
</subclass>
<subclass name="base.RealDataEvent.UniquenessConstraint">
<many-to-one name="event" class="base.RealDataEvent" column="event_id_U"/>
</subclass>
</class>

Then change the corresponding key columns in the many-to-one associations in RealDataEvent. Seems to be working so far.

Thanks!
Chris


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 2 posts ] 

All times are UTC - 5 hours [ DST ]


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.