-->
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.  [ 5 posts ] 
Author Message
 Post subject: "polymorphic" queries, unique subclass fields
PostPosted: Tue Dec 07, 2004 6:40 pm 
Newbie

Joined: Tue Dec 07, 2004 5:06 pm
Posts: 4
Hibernate version:
2.1.6

Mapping documents:

Code:
<?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 package="com.bamboo.web.db.resources">
    <class
        name="FileResourceImpl"
        table="file_resources_test1"
        discriminator-value="fr"
    >
        <id
            name="m_id"
            column="id"
            type="long"
            access="field">
            <generator class="native"/>
        </id>
       
        <discriminator
            column="metadata_type"
            type="string"
        />
           
        <property
            name="m_creator"
            column="creator"
            access="field"
            type="string"
        >
        </property>
       
        <property
            name="m_title"
            column="title"
            access="field"
            type="string"
        >
        </property>
       
        <property
            name="m_path"
            column="path"
            access="field"
            type="string"
        >
        </property>
         
      <property
            name="m_name"
            column="name"
            access="field"
            type="string"
        >
        </property>
           
        <property
            name="m_permission"
            column="permission"
            access="field"
            type="com.bamboo.web.db.hbn.PermissionUserType"
        >
        </property>
           
        <property
            name="m_sHA1URN"
            column="sha1"
            access="field"
            type="string"
        >
        </property>
           
        <subclass
            name="AudioFileResourceImpl"
            discriminator-value="audio">
           
            <property
                name="m_bitRate"
                column="bit_rate"
                access="field"
                type="int"
            >
            </property>
           
            <property
                name="m_genre"
                column="genre"
                access="field"
                type="string"
            >
            </property>
            <property
                name="m_album"
                column="album"
                access="field"
                type="string"
            >
            </property>
         
            <property
                name="m_year"
                column="year"
                access="field"
                type="int"
            >
            </property>
            <property
                name="m_comment"
                column="comment"
                access="field"
                type="string"
            >
            </property>
        </subclass>
    </class>
</hibernate-mapping>


Code between sessionFactory.openSession() and session.close():
Tricky with Spring -- lots of Spring code in between.

Full stack trace of any exception that occurs:
No exceptions.

Name and version of the database you are using:
HSQLDB 1.7.2.2

The generated SQL (show_sql=true):
Having trouble getting it to work with Spring config for some reason...sorry.

Debug level Hibernate log excerpt:
Doesn't say much, but here it is:
[junit] 7761 INFO [main] cfg.SettingsFactory.buildSettings - Use scrollable result sets: true
[junit] 7761 INFO [main] cfg.SettingsFactory.buildSettings - Use JDBC3 getGeneratedKeys(): false
[junit] 7761 INFO [main] cfg.SettingsFactory.buildSettings - Optimize cache for minimal puts: false
[junit] 7771 INFO [main] cfg.SettingsFactory.buildSettings - Query language substitutions: {}


As you can see in the above config file, I have a superclass "FileResourceImpl" and a subclass "AudioFileResourceImpl". I'm querying for a given word that I want to match against fields in both FileResourceImpl and in AudioFileResourceImpl, but I want it to match fields in AudioFileResourceImpl that *are not* in FileResourceImpl.

I'm currently doing the following to give you an idea:

Code:
    public List handlePlainTextRequest(final String name)
        {
        final String query =
            "from FileResourceImpl as fr, AudioFileResourceImpl as afr where " +
            "fr.m_name like ?" +
            "or fr.m_title like ?" +
            "or fr.m_creator like ?" +
            "or afr.m_genre like ?" +
            "or afr.m_album like ?" +
            "or afr.m_comment like ?";
         final String[] names = new String[6];
         Arrays.fill(names, "%"+name+"%");
         return getHibernateTemplate().find(query, names);
         }


This returns a list of raw Objects, though, not FileResourceImpls or AudioFileResourceImpls. As you may have guessed, I'm new to Hibernate and have not done anything with SQL since my college databases class way back when! I'd like the list to return instances of FileResourceImpl and AudioFileResourceImpl. Should I be doing a join instead (I believe the above does an implicit join, but something more specific?)? I basically just want the passed-in name to match (well be "like") any of the string fields of either the superclass or the subclass.

Thanks very much for anyone's help.

-Adam


Top
 Profile  
 
 Post subject:
PostPosted: Tue Dec 07, 2004 9:46 pm 
Beginner
Beginner

Joined: Wed Oct 01, 2003 3:57 am
Posts: 33
Location: Alpharetta, Georgia
Have you looked at the Criteria API for hibernate?

HibernateTemplate.createCriteria(Session session, Class entityClass)

and follow the criteria link to hibernate.

Hibernate reference has a discussion about it in chapter 9, and there are interesting things to read about polymorphic queries in chapter 11


Top
 Profile  
 
 Post subject:
PostPosted: Wed Dec 08, 2004 12:15 am 
Newbie

Joined: Tue Dec 07, 2004 5:06 pm
Posts: 4
I have used criteria queries also using HibernateTemplate, but they don't do anything straight HQL queries don't do, and they don't address the problem above, unfortunately. Was there a reason you suggested Criteria queries? They might be less messy, but otherwise they don't address this issue to my knowledge.

The query I'm talking about above is also different from the typical polymorphic queries for the given reason that I'm looking for matches on AudioFileResourceImpl *subclass* for properties that don't exist in FileResourceImpl *superclass*. None of the discussions of normal polymorphic queries address this case, unless you know of examples outside of the manual or "Hibernate in Action" where this is not the case.

Thanks very much.

-Adam


Top
 Profile  
 
 Post subject:
PostPosted: Wed Dec 08, 2004 1:23 am 
Beginner
Beginner

Joined: Wed Oct 01, 2003 3:57 am
Posts: 33
Location: Alpharetta, Georgia
From chapter 11.6
Quote:
11.6. Polymorphic queries
11.6. Polymorphic queries
A query like:

from eg.Cat as cat

returns instances not only of Cat, but also of subclasses like DomesticCat. Hibernate queries may name any Java class or interface in the from clause. The query will return instances of all persistent classes that extend that class or implement the interface. The following query would return all persistent objects:

from java.lang.Object o
The interface Named might be implemented by various persistent classes:

from eg.Named n, eg.Named m where n.name = m.name
Note that these last two queries will require more than one SQL SELECT. This means that the order by clause does not correctly order the whole result set. (It also means you can't call these queries using Query.scroll().)


The advantage of the criteria is that you can add all those ors that you were after.

As far as straight HQL (polymorphic queries) You should get a list of all elements in that table that are in the FileResourceImpl class hierarchy.

As far as I use them, criteria queries are for loading collections of top-level persistent entities (Parent objects with lazy-loaded children collections for the most part), and HQL is for Report Queries, for loading projected data, as in

"select employee.name, employee.eyeColor, address.id" -- straight RDBMS projection of fields, most often used with inner and/or outer joins.

In the list you will get rows of Object[] arrays, each element of which you will have to cast to the field type expected (String, Long, Date, etc).

Since you seem to be loading objects in the one hierarchy, I thought Criteria queries might be useful. You can iterate through the returned list using getClass(), instanceof, isassignablefrom (see spring's ClassUtils.getShortName() for a nice tool ) - etc, tests to see if it's one of the FileResourceImpl or one of the AudioFileResourceImpl types.

net.sf.hibernate.expression.Expression allows you to use disjunctions (all those "ors" I saw).

Though I don't know if the hibernate folks approve - from the mapping I may assume you're using table-per-class-hierarchy instead of joined-subclass, you can actually filter on the discriminator to be sure you only get the particular types of subclasses you want.

Code:
.add( Expression.eq("metadata_type", "com.bamboo.web.db.resources.AudioFileResourceImpl")


Do you have your showSql = true? I really learned a lot from Hibernate by watching the queries being generated by all the HQL and criteria queries I was using.


Top
 Profile  
 
 Post subject:
PostPosted: Wed Dec 08, 2004 9:43 pm 
Newbie

Joined: Tue Dec 07, 2004 5:06 pm
Posts: 4
I ended up pulling all my fields into the superclass and just querying on FileResourceImpl and keeping the accessors in the subclass. Again, the polymorphism examples are irrelevant for what I'm trying to do -- the case where you want to query by variables that are *only in the subclass*.

The criteria queries give more compile-time checking, but it otherwise doesn't matter.

Thanks for explaining the Object[] returns -- I was completely confused about that. I thought they were straight objects and not arrays!!

Pulling everything into protected variables in the superclass is not ideal, but it works and performs well, and this is a particularly performance-sensitive chunk of code.

Thanks.

-Adam


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