AbstractEmptinessExpression.toSqlString dont append 'where' attribute from a mapping of a set:
I have a class called PortletDefinition with a member of type set called "userAuthorizedUsers" (see mapping below). In the mapping of the set I have an attribute 'where'
It seems that when I use a criteria (see below) with a isEmpty Expression on the "userAuthorizedUsers", the inner select does not use the 'where' part of the set mapping resulting in wrong query result (see generated SQL below).
Is this a hibernate bug or a misuse on my part?
I have tried to fix this in the following way:
1. file QueryableCollection.java - added a new method definition to the interface:
public abstract String getSQLWhereString();
2. file AbstractCollectionPersister.java
added an implementation of the above method:
public String getSQLWhereString() { return sqlWhereString; }
3. file AbstractEmptinessExpression method toSqlString:
added a call to above method:
String where = collectionPersister.getSQLWhereString();
String innerSelect = "(select 1 from " + collectionPersister.getTableName()
+ " where "
+ new ConditionFragment().setTableAlias( sqlAlias ).setCondition( ownerKeys, collectionKeys ).toFragmentString()
+ ((where == null) ? "" : (" and " + where))
+ ")";
This seems to fix the problem
Hibernate version: 3.1.3
From my inspection of the hibernate 3.2.1 code, the problem was not fixed there...
Mapping documents:
a set mapping in ourPortletDefinition class
<set
name="userAuthorizedUsers"
table="DSH_AUTHORIZED_USERS"
lazy="true"
inverse="true"
cascade="all"
sort="unsorted"
where="parent_entity_name like '%PortletDefinition' and type = 'USER'"
>
<key
column="PARENT_PRIMARY_KEY"
foreign-key="none"
>
</key>
<one-to-many
class="com.mercury.dashboard.model.access.AuthorizedUser"
/>
</set>
Code between sessionFactory.openSession() and session.close():
session.createCriteria(PortletDefinition.class).add(Expression.isEmpty("userAuthorizedUsers")).list();
Name and version of the database you are using:
oracle >= 9 (Oracle9Dialect) or sqlserver - happens in both
The generated SQL (show_sql=true):
select this_.PORTLET_DEF_ID as PORTLET1_24_0_,
this_.VERSION as VERSION24_0_,
this_.CUSTOMER_ID as CUSTOMER3_24_0_,
this_.NAME as NAME24_0_,
this_.UUID as UUID24_0_,
this_.DESCRIPTION as DESCRIPT6_24_0_,
this_.TIMEOUT as TIMEOUT24_0_,
this_.DEFAULT_WIDTH as DEFAULT8_24_0_,
...
from DSH_PORTLET_DEFS this_
...
where not exists (select 1 from DSH_AUTHORIZED_USERS where this_.PORTLET_DEF_ID=PARENT_PRIMARY_KEY)
If this is indeed a bug, how can I track it (to know when it is fixed)
Thanks
Yariv Snapir
|