|
From: Kirill M. (JIRA) <nh...@gm...> - 2011-04-14 08:01:13
|
HQL + theta-style join + Enumerable() + select only one entity = strange proxies' behaviour while iterating
-----------------------------------------------------------------------------------------------------------
Key: NH-2650
URL: http://216.121.112.228/browse/NH-2650
Project: NHibernate
Issue Type: Bug
Components: DataProviders / Dialects
Affects Versions: 3.1.0
Reporter: Kirill Medvedev
Priority: Major
I've created a test which consists of two classes:
Man:
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" assembly="Domain" namespace="Domain" default-lazy="true">
<class name="Man" table="Men">
<id name="Id" column="Id">
<generator class="native"/>
</id>
<many-to-one name="Owner" class="Owner" column="OwnerId" cascade="save-update"/>
<property name="Name"/>
</class>
</hibernate-mapping>
Owner:
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" assembly="Domain" namespace="Domain" default-lazy="true">
<class name="Owner" table="Owners">
<id name="Id" column="Id">
<generator class="native"/>
</id>
<property name="Name"/>
<bag name="Men" cascade="save-update">
<key column="OwnerID"/>
<one-to-many class="Man"/>
</bag>
</class>
</hibernate-mapping>
If I write a simple hql-query without theta-joins, I get a lazily-loaded collection of proxies:
IEnumerable<Man> men = session.CreateQuery("from Man").Enumerable<Man>();
I can iterate through this collection without loading proxies:
foreach (Man each in men)
{
//No code here, only iterating... Proxies are not loaded here, as expected.
}
But when I add theta-style join to this query...
IEnumerable<Man> result = session.CreateQuery("select m from Man m left join m.Owner").Enumerable<Man>();
NHibernate generates acceptable TSQL and builds SafetyEnumerable collection
select man0_.Id as col_0_0_
from Men man0_
left outer join Owners owner1_
on man0_.OwnerId = owner1_.Id
but (!) when I add iterating logic without accessing to any properties
foreach (Man each in men)
{
//No code here! Only iterating through elements
}
new queries go to database each iteration, and load each entity:
SELECT man0_.Id as Id1_0_,
man0_.OwnerId as OwnerId1_0_,
man0_.Name as Name1_0_
FROM Men man0_
WHERE man0_.Id = 5098 /* @p0 */
Therefore I can't even convert this IEnumerable<Man> to List<Man> without loading the whole list of objects, because List constructor iterates through IEnumerable collection to add this collection to itself
//public List(IEnumerable<T> collection) - constructor
while (enumerator.MoveNext())
{
this.Add(enumerator.Current);
}
Question: Is this behaviour designed to behave such way intentionally? It's strange that different hql queries return SafetyEnumerable collection which behaves differently while iterating through it (in case of non-theta joined queries, collection's entities are not loaded while iterating through it (without accessing any properties), but in theta-joined queries, entities are loaded while iterating through collection). Strange proxies' behaviour.
Thank you.
--
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators: http://216.121.112.228/secure/Administrators.jspa
-
For more information on JIRA, see: http://www.atlassian.com/software/jira
|