[hibernate-issues] [Hibernate-JIRA] Created: (HHH-4829) Criteria Query with joined-subclass generates incorrect SQL

Rajender Aggarwal (JIRA) noreply at atlassian.com
Fri Jan 22 04:56:18 EST 2010


Criteria Query with joined-subclass generates incorrect SQL
-----------------------------------------------------------

                 Key: HHH-4829
                 URL: http://opensource.atlassian.com/projects/hibernate/browse/HHH-4829
             Project: Hibernate Core
          Issue Type: Bug
          Components: query-criteria
    Affects Versions: 3.3.2
         Environment: Hibernate 3.3.2
MySQL 5.0
            Reporter: Rajender Aggarwal


We have a scenario where joined-sublcass is used for Inheritance. There is a property called 'messageBody' that is present in two Child classes. When the query Criteria created on Parent class and the criteria contains 'messageBody' - the where clause contains like for only one table (the one that appears first in joined-subclass).

I am attaching trimmed version of HBM file, Method that prepares Criteria query, Current SQL and expected SQL.

Please let me know if any further information is required. rajender.aggarwal at gmail.com

---------------------------------------------- HBM File ------------------------------------------------
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping default-cascade="none">
	<class name="com.myproject.core.model.Ad" abstract="true" table="Ad">
		<id name="id" type="long" column="ad_id" unsaved-value="null">
			<generator class="native" />
		</id>
		<property name="subAccount" type="string">
			<column name="subaccount" sql-type="text" />
		</property>
		<many-to-one name="shortCode" column="shortcode_id"
			class="com.myproject.core.model.ShortCode"></many-to-one>
		<many-to-one name="account" column="account_id"
			class="com.myproject.core.model.Account" lazy="false"></many-to-one>

		<joined-subclass name="com.myproject.core.model.D2PAd" extends="com.myproject.core.model.Ad" 
			table="d2pad" batch-size="50">
			<key column="d2pad_id" />
			<property name="createdOn" type="timestamp" column="createdOn"
				not-null="true" />
			<property name="modifiedOn" column="modifiedOn" type="timestamp" />
			<property name="activationDate" column="activation_date"
				type="timestamp" />
			<property name="active" column="active" type="boolean" />
			<property name="ageVerfReq" column="ageverfreq" type="boolean" />
			<property name="deactivationDate" column="deactivation_date"
				type="timestamp" />
			<property name="title" type="string">
				<column name="title" sql-type="text" />
			</property>
			<property name="url" type="string">
				<column name="url" sql-type="text" />
			</property>
			<property name="deleted" column="deleted" type="boolean" />
			<list name="templates" cascade="all,delete-orphan">
				<key column="adId" />
				<index column="sequence" />
				<one-to-many class="com.myproject.d2p.model.D2PAdTemplate" />
			</list>
			<bag name="webPages" cascade="all,delete-orphan">
				<key column="d2pAd" />
				<one-to-many class="com.myproject.d2p.webpage.model.D2PAdWebPage" />
			</bag>	

		</joined-subclass>
		<joined-subclass name="com.myproject.cmm.model.CMMAd" table="cmmad" abstract="true" extends="com.myproject.core.model.Ad" batch-size="50">
			<key column="cmmad_id" />
			<property name="title" type="string">
				<column name="title" sql-type="text" />
			</property>
			<property name="dateTime" column="scheduled_date_time" type="timestamp" />
			<many-to-one name="optInD2PAd" column="optin_d2pad"
				class="com.myproject.core.model.D2PAd"></many-to-one>
			<many-to-one name="destinationGroup" column="contactGroup_Id"
				class="com.myproject.contactgroup.model.ContactGroup"></many-to-one>
			<property name="deleted" column="deleted" type="boolean" />
			
			<joined-subclass name="com.myproject.cmm.model.GeneralCMMAd" table="generalcmmad" extends="com.myproject.cmm.model.CMMAd" batch-size="50">
				<key column="cmmad_id" />
				<property name="messageBody" type="string">
					<column name="messagebody" sql-type="text" />
				</property>
				<property name="optInText" type="string">
					<column name="optin_text" sql-type="text" />
				</property>
			</joined-subclass>
		
			<joined-subclass name="com.myproject.cmm.model.D2PCMMAd" table="d2pcmmad" extends="com.myproject.cmm.model.CMMAd" batch-size="50">
				<key column="cmmad_id" />
				<many-to-one name="d2pAd" column="d2pad_id" class="com.myproject.core.model.D2PAd"></many-to-one>
				<property name="optInText" type="string">
					<column name="optin_text" sql-type="text" />
				</property>					
			</joined-subclass>
			
			<joined-subclass name="com.myproject.cmm.model.OptInCMMAd" table="optincmmad" extends="com.myproject.cmm.model.CMMAd" batch-size="50">
				<key column="cmmad_id" />
				<property name="messageBody" type="string">
					<column name="messagebody" sql-type="text" />
				</property>
			</joined-subclass>
			
			<joined-subclass name="com.myproject.cmm.model.AppointmentCMMAd" table="appointmentcmmad" extends="com.myproject.cmm.model.CMMAd" batch-size="50">
				<key column="cmmad_id" />
				<property name="appointmentDateTime" column="appointment_date_time" type="timestamp" />
				<list name="messageCMMAds" cascade="all,delete-orphan" lazy="false">
					<key column="appointmentCMM" />
					<index column="sequence" />
					<one-to-many class="com.myproject.cmm.model.AppointmentOption" />
				</list>	
			</joined-subclass>			
		</joined-subclass>
	</class>
</hibernate-mapping>

---------------------------------------------- Criteria Query Method  ------------------------------------------------

Input Parameters:
pageNo = 1
accountId = 1
filterMap = [{"messageBody", "test"}]
adClass = com.converdia.cmm.model.CMMAd
rowCount = 10


    protected <T extends Ad> Criteria createCriteriaForAd(Integer pageNo, Long accountId,
            Map<FilterKey, Object> filterMap, Class<T> adClass, boolean rowCount) {
        Criteria crt = this.getSession().createCriteria(adClass);
        if (accountId != null) {
            crt.add(Restrictions.eq("account.id", accountId));
        }
        crt.add(Restrictions.ne("deleted", Boolean.TRUE));
        for (FilterKey key : filterMap.keySet()) {
            switch (key.getFilterType()) {
                case FilterKey.CONDITION_EQUALS_TYPE:
                    crt.add(Restrictions.eq(key.getFieldKey(), filterMap.get(key)));
                    break;
                case FilterKey.CONDITION_LIKE_TYPE:
                    String srch = ((String) filterMap.get(key)).replace('*', '%');
                    crt.add(Restrictions.like(key.getFieldKey(), '%' + srch + '%'));
                    break;
                case FilterKey.CONDITION_GREATER:
                    crt.add(Restrictions.ge(key.getFieldKey(), filterMap.get(key)));
                    break;
                case FilterKey.CONDITION_LESSER:
                    crt.add(Restrictions.le(key.getFieldKey(), filterMap.get(key)));
                    break;
                case FilterKey.CONDITION_BETWEEN:
                    Object[] values = (Object[]) filterMap.get(key);
                    crt.add(Restrictions.between(key.getFieldKey(), values[0], values[1]));
                    break;
                default:
                    break;
            }
        }
        if (rowCount) {
            crt.setProjection(Projections.projectionList().add(Projections.rowCount()));
        } else {
            crt.setFirstResult((pageNo - 1) * 10).setMaxResults(10);
        }

        return crt;
    }


---------------------------------------------- Filter Key Class  ------------------------------------------------

package com.myproject.core.helper;

public class FilterKey {

    public static final int CONDITION_LIKE_TYPE = 1;
    public static final int CONDITION_EQUALS_TYPE = 2;
    public static final int CONDITION_GREATER = 3;
    public static final int CONDITION_LESSER = 4;
    public static final int CONDITION_BETWEEN = 5;

    public FilterKey() {

    }

    public FilterKey(String fieldKey, Integer filterType) {
        this.fieldKey = fieldKey;
        this.filterType = filterType;
    }

    private String fieldKey;
    private Integer filterType;

    public String getFieldKey() {
        return this.fieldKey;
    }

    public void setFieldKey(String fieldKey) {
        this.fieldKey = fieldKey;
    }

    public Integer getFilterType() {
        return this.filterType;
    }

    public void setFilterType(Integer filterType) {
        this.filterType = filterType;
    }

}

---------------------------------------------- Generated Query  ------------------------------------------------

select
        count(*)  as y0_ 
    from
        cmmad this_ 
    inner join
        Ad this_1_ 
            on this_.cmmad_id=this_1_.ad_id 
    left outer join
        generalcmmad this_2_ 
            on this_.cmmad_id=this_2_.cmmad_id 
    left outer join
        d2pcmmad this_3_ 
            on this_.cmmad_id=this_3_.cmmad_id 
    left outer join
        optincmmad this_4_ 
            on this_.cmmad_id=this_4_.cmmad_id 
    left outer join
        appointmentcmmad this_5_ 
            on this_.cmmad_id=this_5_.cmmad_id 
    where
        this_.deleted<>? 
        and this_2_.messagebody like ?

---------------------------------------------- Expected Query  ------------------------------------------------

select
        count(*)  as y0_ 
    from
        cmmad this_ 
    inner join
        Ad this_1_ 
            on this_.cmmad_id=this_1_.ad_id 
    left outer join
        generalcmmad this_2_ 
            on this_.cmmad_id=this_2_.cmmad_id 
    left outer join
        d2pcmmad this_3_ 
            on this_.cmmad_id=this_3_.cmmad_id 
    left outer join
        optincmmad this_4_ 
            on this_.cmmad_id=this_4_.cmmad_id 
    left outer join
        appointmentcmmad this_5_ 
            on this_.cmmad_id=this_5_.cmmad_id 
    where
        this_.deleted<>? 
        and (this_2_.messagebody like ? or this_4_.messagebody like ?)


-- 
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators: http://opensource.atlassian.com/projects/hibernate/secure/Administrators.jspa
-
For more information on JIRA, see: http://www.atlassian.com/software/jira

        


More information about the hibernate-issues mailing list