-->
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.  [ 4 posts ] 
Author Message
 Post subject: <joined-subclass> and .class in HQL lead to incorrect
PostPosted: Fri Jan 23, 2004 7:27 am 
Beginner
Beginner

Joined: Wed Nov 26, 2003 11:53 am
Posts: 26
Location: Netherlands
Hello, I have a case where using .class in a HQL query leads to incorrect SQL. I could be using the .class in an incorrect way, but paragraph 10.7 of the manual is not entirely clear if the .class is only for <any> mappings or is always available.

The joined-subclasses are the "PilootImage", "InternalImage" and "ExternalImage" classes.

Mapping (w. XDoclet 1.2):

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>
    <class
        name="nl.sogeti.piloot.server.model.PilootImage"
        table="image"
        dynamic-update="false"
        dynamic-insert="false"
    >

        <id
            name="persistentId"
            column="id"
            type="java.lang.Long"
        >
            <generator class="assigned">
            </generator>
        </id>

        <version
            name="hibernateVersion"
            type="java.lang.Integer"
            column="hibernateVersion"
        />

        <property
            name="name"
            type="java.lang.String"
            update="true"
            insert="true"
            column="name"
        />

        <property
            name="version"
            type="long"
            update="true"
            insert="true"
            column="version"
        />

        <property
            name="lastversion"
            type="long"
            update="true"
            insert="true"
            column="lastversion"
        />

        <property
            name="deleted"
            type="yes_no"
            update="true"
            insert="true"
            column="deleted"
        />

        <!--
            To add non XDoclet property mappings, create a file named
                hibernate-properties-PilootImage.xml
            containing the additional properties and place it in your merge dir.
        -->

        <joined-subclass
            name="nl.sogeti.piloot.server.model.ExternalImage"
            table="externalimage"
            dynamic-update="false"
            dynamic-insert="false"
        >
        <key
            column="id"
        />
        <property
            name="conceptId"
            type="int"
            update="true"
            insert="true"
            column="conceptid"
        />

        <property
            name="databaseId"
            type="int"
            update="true"
            insert="true"
            column="databaseid"
        />

        <property
            name="synonymNumber"
            type="int"
            update="true"
            insert="true"
            column="synonymnumber"
        />

        </joined-subclass>
        <joined-subclass
            name="nl.sogeti.piloot.server.model.InternalImage"
            table="internalimage"
            dynamic-update="false"
            dynamic-insert="false"
        >
        <key
            column="id"
        />
        <property
            name="type"
            type="java.lang.String"
            update="true"
            insert="true"
            column="internal_type"
        />

        <property
            name="imageBytes"
            type="binary"
            update="true"
            insert="true"
            column="internal_binary"
        />

        </joined-subclass>

    </class>

</hibernate-mapping>


My code: the commented-out code is the version that will fail. The way it is now it works correctly, but I need to select either the Internal- or ExternalImages. HibernateUtil is a wrapper around a Hibernate Session.

Code:
   private List findImagesOfSubscription(HibernateUtil persistency, long id, String className) throws HibernateException
   {
      Set result = new HashSet();
      
      String messageImagesQuery =
         "select new nl.sogeti.piloot.server.framework.VersionedId(pim.id, pim.version, pim.lastversion, pim.deleted) "
            + "from Subscription as sub "
            + "join elements(sub.books) as bk "
            + "join elements(bk.messages) as msg "
            + "join elements(msg.messageItems) as itm "
            + "join itm.pilootImage as pim "
            + "where (sub.id = ?) ";
//            + "and (pim.class = ?)";
            
      List messageImages = persistency.find(messageImagesQuery, new Long(id), Hibernate.LONG);
//      List messageImages = persistency.find(messageImagesQuery, new Long(id), Hibernate.LONG, className, Hibernate.STRING);
      result.addAll(messageImages);
      
      String pictureBookImagesQuery =
         "select new nl.sogeti.piloot.server.framework.VersionedId(pim.id, pim.version, pim.lastversion, pim.deleted) "
            + "from Subscription as sub "
            + "join elements(sub.books) as bk "
            + "join elements(bk.pictureBooks) as pb "
            + "join pb.pilootImage as pim "
            + "where (sub.id = ?) ";
//            + "and (pim.class = ?)";
            
      List picturebookImages = persistency.find(pictureBookImagesQuery, new Long(id), Hibernate.LONG);
//      List picturebookImages = persistency.find(pictureBookImagesQuery, new Long(id), Hibernate.LONG, className, Hibernate.STRING);
      result.addAll(picturebookImages);
      
      String pictureBookItemsImagesQuery =
         "select new nl.sogeti.piloot.server.framework.VersionedId(pim.id, pim.version, pim.lastversion, pim.deleted) "
            + "from Subscription as sub "
            + "join elements(sub.books) as bk "
            + "join elements(bk.pictureBooks) as pb "
            + "join elements(pb.items) as pbi "
            + "join pbi.pilootImage as pim "
            + "where (sub.id = ?) ";
//            + "and (pim.class = ?)";
            
      List picturebookItemImages = persistency.find(pictureBookItemsImagesQuery, new Long(id), Hibernate.LONG);
//      List picturebookItemImages = persistency.find(pictureBookItemsImagesQuery, new Long(id), Hibernate.LONG, className, Hibernate.STRING);
      result.addAll(picturebookItemImages);
      
      String userPortraitQuery =
         "select new nl.sogeti.piloot.server.framework.VersionedId(pim.id, pim.version, pim.lastversion, pim.deleted) "
            + "from Subscription as sub "
            + "join elements(sub.users) as usr "
            + "join usr.portrait as pim "
            + "where (sub.id = ?) ";
//            + "and (pim.class = ?)";
            
      List userPortraitImages = persistency.find(userPortraitQuery, new Long(id), Hibernate.LONG);
//      List userPortraitImages = persistency.find(userPortraitQuery, new Long(id), Hibernate.LONG, className, Hibernate.STRING);
      result.addAll(userPortraitImages);
      
      return new ArrayList(result);
   }


Now the not working (commented out) version yields this SQL. I formatted it for clarity. I just show the first query, the others are similar.

Code:
select
   pilootimag4_.id as x0_0_,
   pilootimag4_.version as x1_0_,
   pilootimag4_.lastversion as x2_0_,
   pilootimag4_.deleted as x3_0_
from
   subscription subscripti0_
   inner join book books1_ on
      subscripti0_.id=books1_.fk_subscription
      inner join message messages2_ on
         books1_.id=messages2_.fk_book
         inner join messageitem messageite3_ on
            messages2_.id=messageite3_.fk_message
               inner join image pilootimag4_ on
                  messageite3_.fk_image=pilootimag4_.id
where
   ((subscripti0_.id=? ))
and (
   (case
      when pilootimag4__1_.id is not null then 1
      when pilootimag4__2_.id is not null then 2
      when pilootimag4_.id is not null then 0
   end=? ))


...and yields the error

Code:
2004-01-23 11:16:17,368 WARN  [net.sf.hibernate.util.JDBCExceptionReporter] SQL Error: 1109, SQLState: S1000
2004-01-23 11:16:17,368 ERROR [net.sf.hibernate.util.JDBCExceptionReporter] General error,  message from server: "Unknown table 'pilootimag4__1_' in where clause"
2004-01-23 11:16:17,368 DEBUG [net.sf.hibernate.impl.BatcherImpl] done closing: 0 open PreparedStatements, 0 open ResultSets
2004-01-23 11:16:17,368 DEBUG [net.sf.hibernate.impl.BatcherImpl] closing statement
2004-01-23 11:16:17,368 DEBUG [net.sf.hibernate.util.JDBCExceptionReporter] SQL Exception
java.sql.SQLException: General error,  message from server: "Unknown table 'pilootimag4__1_' in where clause"
   at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:1651)
   at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:889)
   at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:956)
   at com.mysql.jdbc.Connection.execSQL(Connection.java:1874)
   at com.mysql.jdbc.PreparedStatement.executeQuery(PreparedStatement.java:1538)
   at org.jboss.resource.adapter.jdbc.WrappedPreparedStatement.executeQuery(WrappedPreparedStatement.java:302)
   at net.sf.hibernate.impl.BatcherImpl.getResultSet(BatcherImpl.java:83)
   at net.sf.hibernate.loader.Loader.getResultSet(Loader.java:794)
   at net.sf.hibernate.loader.Loader.doQuery(Loader.java:188)
   at net.sf.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:132)
   at net.sf.hibernate.loader.Loader.doList(Loader.java:949)
   at net.sf.hibernate.loader.Loader.list(Loader.java:940)
   at net.sf.hibernate.hql.QueryTranslator.list(QueryTranslator.java:833)
   at net.sf.hibernate.impl.SessionImpl.find(SessionImpl.java:1475)
   at net.sf.hibernate.impl.SessionImpl.find(SessionImpl.java:1454)
   at nl.sogeti.piloot.server.model.persistency.HibernateUtil.find(HibernateUtil.java:130)


and for completeness, the working version, without any mention of .class. Again formatted for clarity.

Code:
select
   messages2_.id as x0_0_,
   messages2_.version as x1_0_,
   messages2_.lastversion as x2_0_,
   messages2_.deleted as x3_0_
from
   subscription subscripti0_
   inner join book books1_ on
      subscripti0_.id=books1_.fk_subscription
      inner join message messages2_ on
      books1_.id=messages2_.fk_book
where
   (subscripti0_.id=? )


So what is the matter here? A bug, or wrong usage of .class?


Top
 Profile  
 
 Post subject: I am seeing this also
PostPosted: Fri Jan 23, 2004 10:55 am 
Newbie

Joined: Fri Jan 23, 2004 10:52 am
Posts: 3
I have a class BioSequence with a joined subclass Contig

"from Contig c" returns all contigs
"from BioSequence b where b.class=Contig" returns all BioSequences that are NOT contigs.
"from BioSequence b where not b.class=Contig" returns all contigs.

Dave


Top
 Profile  
 
 Post subject:
PostPosted: Fri Jan 23, 2004 4:25 pm 
Hibernate Team
Hibernate Team

Joined: Sun Sep 14, 2003 3:54 am
Posts: 7256
Location: Paris, France
Quote:
So what is the matter here? A bug, or wrong usage of .class?

You decared the itm.pilootImage association as an association between item and the super class PilootImage.
So Hibernate will only load PilootImage and not it's subclass properties. It cannot check the class type.

Post a simple test case to Jira, At least, an explicit Hibernate Exception should have been raised.

_________________
Emmanuel


Top
 Profile  
 
 Post subject:
PostPosted: Fri Jan 23, 2004 7:28 pm 
Hibernate Team
Hibernate Team

Joined: Tue Aug 26, 2003 12:50 pm
Posts: 5130
Location: Melbourne, Australia
There is already an issue in JIRA relating to this.


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