-->
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.  [ 14 posts ] 
Author Message
 Post subject: search/filter by subclass from a where clause
PostPosted: Thu Mar 09, 2006 5:27 pm 
Newbie

Joined: Wed Feb 08, 2006 11:40 pm
Posts: 8
I've got a class (we'll call it Superclass) with 2 subclasses (we'll call these SubA and SubB) and they are mapped using
<joined-subclass name="..." table="..."/>

Things are set up property but I can't do a search within a specific subclass.
My hql looks like this:
"from Superclass as superclass where ..."

I need to filter by subclass within the where clause, is this possible? I need this for a search that normally displays results in a combined list. But we have an option that allows the user to not show SubA or SubB. In the future we'll probably add at least 2 more subclasses so it seemed logical to do it this way.

This is an error I'm getting while trying "superclass.class.name =..."
[INFO] SuperclassDao - Using where clause: superclass.class.name =:cls0
org.hibernate.QueryException: could not resolve property: name of: Superclass [from Superclass as superclass where superclass.class.name =:cls0]
at org.hibernate.persister.entity.AbstractPropertyMapping.throwPropertyException(AbstractPropertyMapping.java:43)
at org.hibernate.persister.entity.AbstractPropertyMapping.toType(AbstractPropertyMapping.java:37)
at org.hibernate.persister.entity.AbstractEntityPersister.toType(AbstractEntityPersister.java:1264)

I am setting the value (because I'm setting it exactly the same way as I did for other fields. I suspect its because class.name isn't mapped(?).


Top
 Profile  
 
 Post subject:
PostPosted: Thu Mar 09, 2006 5:47 pm 
Expert
Expert

Joined: Mon Jan 09, 2006 5:01 pm
Posts: 311
Location: Sacramento, CA
can you post the entire "SuperClass" mapping file
and the exact java code to run the HQL query...
thx.

off-hand not sure what you are doing with:
superclass.class.name =:cls0

that looks strange to me with the "class.name"...
normally it would be something like:
superclass.attribute=:attr

_________________
-JT

If you find my replies helpful, please rate by clicking 'Y' on them. I appreciate it.


Top
 Profile  
 
 Post subject: hbm file
PostPosted: Thu Mar 09, 2006 7:09 pm 
Newbie

Joined: Wed Feb 08, 2006 11:40 pm
Posts: 8
I gotta trim down the hbm and rename the classes. I'm not sure I should be exposing too much company information... so here goes:

<hibernate-mapping>
<class
name="Superclass"
table="superclass"
dynamic-update="false"
dynamic-insert="false"
optimistic-lock="version"
>
<id
name="id"
column="n_Id"
type="java.lang.Integer"
unsaved-value="null"
>
<generator class="native">
</generator>
</id>
<version name="version" column="n_Version"/>

[ a bunch of properties ]

<joined-subclass name="SubA" table="suba">
<key column="n_SubAId"/>

[ a bunch of properties ]

</joined-subclass>

<joined-subclass name="SubB" table="subb">
<key column="n_SubBId"/>

[ a bunch of properties ]

</joined-subclass>

</class>

</hibernate-mapping>


Top
 Profile  
 
 Post subject: Java code being used
PostPosted: Thu Mar 09, 2006 7:15 pm 
Newbie

Joined: Wed Feb 08, 2006 11:40 pm
Posts: 8
String where = "superclass.class.name=:cls0";
Query query = getSession().createQuery("from Superclass as superclass where " + where);
query.setParameter("cls0", "SubA");

I've removed a bunch of code, but my where clause also contains properties for doing a text search on many of the fields. I'm trying to make it so if they don't specify which classes to remove, then all subclasses of Superclass will be included in the search. If they specifiy, then some will get filtered out.

So the goal is that if later, we also add SubC and SubD, that the user can search for items with a title like "reveng" that are of types SubA, SubC and SubD (but not SubB).


Top
 Profile  
 
 Post subject:
PostPosted: Thu Mar 09, 2006 7:17 pm 
Newbie

Joined: Wed Feb 08, 2006 11:40 pm
Posts: 8
.class.name

I was hoping this would work something like: getClass().getName().


Top
 Profile  
 
 Post subject:
PostPosted: Thu Mar 09, 2006 7:33 pm 
Expert
Expert

Joined: Mon Jan 09, 2006 5:01 pm
Posts: 311
Location: Sacramento, CA
why not create a separate classes that represent your subclasses, and use "discriminator" with the super class table. That way you can work at the subclass level in your java code?

search on "discriminator" in the reference.pdf for examples

http://www.hibernate.org/hib_docs/v3/reference/en/pdf/hibernate_reference.pdf

_________________
-JT

If you find my replies helpful, please rate by clicking 'Y' on them. I appreciate it.


Top
 Profile  
 
 Post subject:
PostPosted: Thu Mar 09, 2006 8:59 pm 
Newbie

Joined: Wed Feb 08, 2006 11:40 pm
Posts: 8
It seems like using subclass instead of joined-subclass forces us to merge all the fields from all subclasses into the same table. This is something we do not want to do. This will make it harder in the future for adding new subclasses since we would have to update the table with a ton of existing data, and a ton of existing fields, and add another ton of fields.

Is there a way to use the discriminator property as something we search for in a hql query?

In the current setup, I can do a hql query like: "from SubA ..." and then join the results with a second query of "from SubB ..." but it just feels like the wrong way to do it (especially since it means going through the list of results (then again when I actually use them)


Top
 Profile  
 
 Post subject: I am not certain if this is an acceptable solution, but...
PostPosted: Thu Mar 09, 2006 11:43 pm 
Beginner
Beginner

Joined: Mon Mar 14, 2005 6:07 pm
Posts: 36
With joined subclasses there is no discriminator (that's the benefit of splitting classes into their own tables), but nothing should prevent you from rolling your own:

Code:
class Superclass {
    protected abstract String getDiscriminator();
    protected void setDiscriminator( String ignored ) {
    }
...
}

class SubclassA {
    protected String getDiscriminator() {
        return getClass().getName();
    }
....
}

class SubclassB {
    protected String getDiscriminator() {
        return getClass().getName();
    }
...
}

Map discriminator in a usual way using property mapping, and add a string field for it to your table. You can now run queries like this:

Code:
from Superclass where discriminator in (:class_names)

where :class_names is a collection of names of subclasses that you need to include in the results.

I hope this helps.


Top
 Profile  
 
 Post subject: query joined-sublass
PostPosted: Fri Mar 10, 2006 6:08 am 
Newbie

Joined: Fri Jun 10, 2005 4:18 am
Posts: 3
hi sodamnmad,

I have got exactly the same requirement as yours.
have you got the answer?

thx,

.satria.


Top
 Profile  
 
 Post subject:
PostPosted: Fri Mar 10, 2006 1:22 pm 
Expert
Expert

Joined: Mon Jan 09, 2006 5:01 pm
Posts: 311
Location: Sacramento, CA
what "skalinic" suggested makes sense. You'd be able to query via subclass or via superclass w/home-brewed descriminator.

_________________
-JT

If you find my replies helpful, please rate by clicking 'Y' on them. I appreciate it.


Top
 Profile  
 
 Post subject:
PostPosted: Sun Mar 12, 2006 10:24 pm 
Newbie

Joined: Fri Jun 10, 2005 4:18 am
Posts: 3
yes, indeed i decided to have my own home-brewed discriminator, and then based on that i query straight to the subclass.

thanks,

.satria.


Top
 Profile  
 
 Post subject: Re: I am not certain if this is an acceptable solution, but.
PostPosted: Mon Mar 13, 2006 5:38 pm 
Newbie

Joined: Wed Feb 08, 2006 11:40 pm
Posts: 8
skalinic wrote:
With joined subclasses there is no discriminator (that's the benefit of splitting classes into their own tables), but nothing should prevent you from rolling your own:

Map discriminator in a usual way using property mapping, and add a string field for it to your table. You can now run queries like this:

Code:
from Superclass where discriminator in (:class_names)

where :class_names is a collection of names of subclasses that you need to include in the results.

I hope this helps.


Thanks, I'll use this.


Top
 Profile  
 
 Post subject:
PostPosted: Mon Mar 13, 2006 10:09 pm 
Expert
Expert

Joined: Mon Jan 09, 2006 5:01 pm
Posts: 311
Location: Sacramento, CA
I checked out your original attempt a little further and found that you can do exactly what you wanted to do - you just had the wrong syntax in your HQL...

try:

qry=session.createQuery("from Superclass sc where sc.class=" +
"SubA");


This works! I just tested it in my own code. No need for descriminator values at all. (don't need home-brewed ones either).

_________________
-JT

If you find my replies helpful, please rate by clicking 'Y' on them. I appreciate it.


Top
 Profile  
 
 Post subject:
PostPosted: Mon Mar 20, 2006 12:50 pm 
Expert
Expert

Joined: Mon Jan 09, 2006 5:01 pm
Posts: 311
Location: Sacramento, CA
sodamnmad -- just curious - did you ever get this working by only using query by subclass (no [home-brewed]discriminator)?


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 14 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.