Win a copy of The Little Book of Impediments (e-book only) this week in the Agile and Other Processes forum!
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic

polymorphic queries

 
Sujan Pradhan
Greenhorn
Posts: 11
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi,

This may sound trivial and it probably is, but I'm having problems accessing data belonging to subclasses when querying an abstract class.

For example, if I do:

session.createCriteria( ContentVO.class ).list();

It returns instances of ContentVO and its subclasses. So I save a vector of ContentVOs like this from the resultset:

ContentVOSet conVOSet = new ContentVOSet();
...
ContentVO conVO =
(ContentVO) resultset.get(i);

conVOSet.addContent( conVO );

I can access all the data for ContentVO, however if I have let's say LinkVO as the subclass then how do I access it? Do I need to reformulate my query or is there any way I can get access to the subclass?

Thanks.


Mapping documents:

<hibernate-mapping package...>

<class name="ContentVO" table="content_table"
dynamic-update="true" optimistic-lock="version">
...

<joined-subclass name="LinkVO" table="link_table">
<key column="link_id"/>
<property name="contentIDFK" column="content_id_fk" not-null="true"/>
</joined-subclass>

</class>
</hibernate-mapping package>


Hibernate version: 3.1

Name and version of the database you are using:
MYSQL 4.1

Note: I've crossed post this in Hibernate.org forum and haven't had any luck with it yet.

TIA.
 
pascal betz
Ranch Hand
Posts: 547
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
session.createCriteria( ContentVO.class ).list(); will give you ContentVO and all of its subclasses.

so what could session.createCriteria( LinkVO.class ).list(); return ?

pascal
 
Sujan Pradhan
Greenhorn
Posts: 11
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Well, that will only return instances of LinkVO.

There are other subclasses of ContentVO that I'd like to access, not just LinkVO; it would be simpler to do this:

session.createCriteria( ContentVO.class ).list();
(this is from hibernate document; also here- http://www-128.ibm.com/developerworks/java/library/j-hibernate/ if you search for 'querying abstract classes' you will get to a similar example)

The query above returns ContentVO as well as all its subclasses.

However, I'm clueless as to how to access the subclasses; there must be some additional mapping that needs to be done, otherwise I don't see how it's possible to access them.

Any clues?

Many thanks!
 
Mark Spritzler
ranger
Sheriff
Posts: 17278
6
IntelliJ IDE Mac Spring
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
How about if you cast those objects to the subclass? Obviously, in that case you need to first check to make sure it is an instanceof.

Mark
 
Sujan Pradhan
Greenhorn
Posts: 11
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
If I query like this:

session.createCriteria( ContentVO.class ).list();

it returns a ContentVO. And if I try to cast to a subclass like this:

if( linkVO instanceof ContentVO ) {
ContentVO conVO =
(LinkVO) resultset.get(i);
}

I get a class cast exception error as expected b/c the resultset is returned as a ContentVO type and not a LinkVO.

Is this example a correct implementation of what you had in mind?
 
Sujan Pradhan
Greenhorn
Posts: 11
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
It seems to me that only way to avoid the class cast exception would be to alter the query to return a LinkVO:

session.createCriteria( LinkVO.class ).list();

However, doing so defeats the purpose of being able to access the data for all the subclasses of ContentVO in one go...

I am still clueless at this point :roll:
 
pascal betz
Ranch Hand
Posts: 547
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
whats this resultset.get(i) ?
is resultset a JDBC ResultSet ? where does it come from ? why do you need to do this ? the persistent items are in the List returned by the criteria. Without showing some more code we can not tell why you have a class cast exception. but to me it looks like:


if you want to query for a hierarchy and then work on the items:

(assuming you have java 1.5. otherwise just use the normal iterator way to loop.

pascal
 
Sujan Pradhan
Greenhorn
Posts: 11
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
The resultset represents a list (it's just a variable); no JDBC is used here- strictly hibernate. Sorry for the ambiguity.

The enhanced-for loop is quite nice to use and it got rid of the class cast exception, however the instanceof block is never executed- another words 'linkVO' is not an instance of 'ContentVO' when the for-loop is executed. That could only mean it returns a list of ContentVOs. I will post my hbm mapping file as well as the code to show you what I've done.

The hbm.xml mapping:


Code for retrieving result set:


Also, the entity class LinkVO extends ContentVO (consistence with inheritance hbm mapping).

I've also checked to make sure that relationships between the two are actually implemented by Hibernate by changing the query to this:



My experience so far has been that if the criteria is the Base class then it only returns the the Base class and not its subclasses ; obviously, it would be same if the criteria was a subclass (but I am also able to access all Base class variables via inheritance).

Yet still, I am not able to access all the subclasses in one go if my criteria is a Base class (per hibernate documentation); is my mapping wrong or what is it that I am missing (pulling my hair out)?

Thanks!
 
Sujan Pradhan
Greenhorn
Posts: 11
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Just to bring this to closure...

The above mapping and DAO code actually worked; I am not sure why it didn't work the first time around.
 
Don't get me started about those stupid light bulbs.
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic