Skip to content

Commit 97e717f

Browse files
stuartcarniehazzik
authored andcommitted
NH-2888 - Add support to ICriteria to eager fetch lazy properties
Allows fetching of root entity, one-to-one and many-to-one associations
1 parent 4c38acb commit 97e717f

23 files changed

+549
-26
lines changed
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
using System.Collections.Generic;
2+
3+
namespace NHibernate.Test.Criteria.FetchAllProperties
4+
{
5+
public class Article
6+
{
7+
public Article()
8+
{
9+
Comments = new HashSet<Comment>();
10+
}
11+
12+
public virtual long Id { get; set; }
13+
14+
public virtual string Title { get; set; }
15+
16+
public virtual string Description { get; set; }
17+
18+
public virtual ISet<Comment> Comments { get; set; }
19+
20+
public virtual ArticleExtension ArticleExtension { get; set; }
21+
}
22+
23+
public class ArticleExtension
24+
{
25+
public virtual long Id { get; set; }
26+
27+
public virtual Article Article { get; set; }
28+
29+
public virtual int Rating { get; set; }
30+
31+
public virtual string Notes { get; set; }
32+
}
33+
34+
public class Comment
35+
{
36+
public virtual long Id { get; set; }
37+
38+
public virtual string Subject { get; set; }
39+
40+
public virtual string Text { get; set; }
41+
42+
public virtual Article Article { get; set; }
43+
}
44+
}
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
<?xml version="1.0" encoding="utf-8" ?>
2+
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"
3+
assembly="NHibernate.Test"
4+
namespace="NHibernate.Test.Criteria.FetchAllProperties"
5+
default-access="property"
6+
default-lazy="true">
7+
8+
<class name="Article" table="Article">
9+
<id name="Id" type="Int64">
10+
<generator class="native"/>
11+
</id>
12+
<property name="Title" />
13+
<property name="Description" lazy="true"/>
14+
<set name="Comments" inverse="true" cascade="all-delete-orphan">
15+
<key column="article_id"/>
16+
<one-to-many class="Comment"/>
17+
</set>
18+
19+
<one-to-one name="ArticleExtension" class="ArticleExtension" cascade="all" lazy="false" />
20+
</class>
21+
22+
<class name="ArticleExtension" table="ArticleExtension">
23+
<id name="Id" type="Int64">
24+
<generator class="foreign">
25+
<param name="property">Article</param>
26+
</generator>
27+
</id>
28+
29+
<property name="Rating" />
30+
<property name="Notes" lazy="true" />
31+
32+
<one-to-one name="Article" class="Article" constrained="true" />
33+
</class>
34+
35+
<class name="Comment" table="Comment">
36+
<id name="Id" type="Int64">
37+
<generator class="native" />
38+
</id>
39+
<property name="Subject" />
40+
<property name="Text" lazy="true"/>
41+
<many-to-one name="Article" column="article_id"/>
42+
</class>
43+
44+
</hibernate-mapping>
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
namespace NHibernate.Test.Criteria.FetchAllProperties
2+
{
3+
public class BlogPost
4+
{
5+
public virtual long Id { get; set; }
6+
7+
public virtual string Title { get; set; }
8+
9+
public virtual string Description { get; set; }
10+
}
11+
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
<?xml version="1.0" encoding="utf-8" ?>
2+
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"
3+
assembly="NHibernate.Test"
4+
namespace="NHibernate.Test.Criteria.FetchAllProperties"
5+
default-access="property"
6+
default-lazy="true">
7+
8+
<class name="BlogPost" table="BlogPost">
9+
<id name="Id" type="Int64">
10+
<generator class="native"/>
11+
</id>
12+
<property name="Title" />
13+
<property name="Description" lazy="true"/>
14+
</class>
15+
16+
</hibernate-mapping>
Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
using System;
2+
using System.Collections;
3+
using NUnit.Framework;
4+
5+
namespace NHibernate.Test.Criteria.FetchAllProperties
6+
{
7+
[TestFixture]
8+
public class FetchAllPropertiesTests : TestCase
9+
{
10+
#region Overrides of TestCase
11+
12+
protected override string MappingsAssembly
13+
{
14+
get { return "NHibernate.Test"; }
15+
}
16+
17+
protected override IList Mappings
18+
{
19+
get
20+
{
21+
return new[]
22+
{
23+
"Criteria.FetchAllProperties.BlogPost.hbm.xml"
24+
};
25+
}
26+
}
27+
28+
protected override void OnSetUp()
29+
{
30+
using (ISession session = OpenSession())
31+
{
32+
ITransaction t = session.BeginTransaction();
33+
34+
BlogPost blogPost = new BlogPost();
35+
blogPost.Title = "ICriteria supports eager property fetch!";
36+
blogPost.Description = "It really does!";
37+
session.Save(blogPost);
38+
39+
t.Commit();
40+
}
41+
}
42+
43+
protected override void OnTearDown()
44+
{
45+
using (ISession session = sessions.OpenSession())
46+
{
47+
session.Delete("from System.Object");
48+
session.Flush();
49+
}
50+
}
51+
52+
#endregion
53+
54+
[Test]
55+
public void DidLoadDescription()
56+
{
57+
BlogPost result;
58+
using (ISession session = sessions.OpenSession())
59+
{
60+
result = session.CreateCriteria(typeof(BlogPost))
61+
.SetLazyPropertyFetchMode(LazyPropertyFetchMode.Select)
62+
.UniqueResult<BlogPost>();
63+
64+
65+
}
66+
67+
Assert.DoesNotThrow(
68+
delegate
69+
{
70+
Assert.That(String.IsNullOrEmpty(result.Description), Is.False, "Should have been a value in Description");
71+
}, "Should not have thrown an exception accessing the Description property");
72+
}
73+
74+
[Test]
75+
public void ShouldThrowExceptionWhenAccessingLazyPropertyOutsideSession()
76+
{
77+
BlogPost result;
78+
using (ISession session = sessions.OpenSession())
79+
{
80+
result = session.CreateCriteria(typeof(BlogPost))
81+
.UniqueResult<BlogPost>();
82+
83+
84+
}
85+
86+
Assert.Throws<LazyInitializationException>(
87+
delegate
88+
{
89+
Assume.That(String.IsNullOrEmpty(result.Description), Is.True);
90+
}, "Should have thrown an exception accessing the Description property");
91+
}
92+
}
93+
}
Lines changed: 175 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,175 @@
1+
using System;
2+
using System.Collections;
3+
using System.Linq;
4+
using NUnit.Framework;
5+
6+
namespace NHibernate.Test.Criteria.FetchAllProperties
7+
{
8+
[TestFixture]
9+
public class FetchAllPropertiesTestsWithRelationships : TestCase
10+
{
11+
#region Overrides of TestCase
12+
13+
protected override string MappingsAssembly
14+
{
15+
get { return "NHibernate.Test"; }
16+
}
17+
18+
protected override IList Mappings
19+
{
20+
get
21+
{
22+
return new[]
23+
{
24+
"Criteria.FetchAllProperties.Article.hbm.xml"
25+
};
26+
}
27+
}
28+
29+
protected override void OnSetUp()
30+
{
31+
using (ISession session = OpenSession())
32+
{
33+
ITransaction t = session.BeginTransaction();
34+
35+
var article = new Article
36+
{
37+
Title = "Article one",
38+
Description = "The descripition for article one",
39+
};
40+
article.Comments.Add(new Comment { Article = article, Subject = "Cool stuff", Text = "Cool stuff comment" });
41+
article.Comments.Add(new Comment { Article = article, Subject = "Could it be true?", Text = "Fetch all in ICriteria rules" });
42+
article.ArticleExtension = new ArticleExtension { Article = article, Rating = 3, Notes = "A few notes" };
43+
session.Save(article);
44+
45+
var article2 = new Article
46+
{
47+
Title = "Article two",
48+
Description = "The descripition for article two",
49+
};
50+
article2.Comments.Add(new Comment { Article = article, Subject = "The beatles", Text = "Are a great band" });
51+
article2.Comments.Add(new Comment { Article = article, Subject = "See you thursday", Text = "Can't wait to grab beers at the new bar!" });
52+
article2.ArticleExtension = new ArticleExtension { Article = article2, Rating = 5, Notes = "I don't like notes" };
53+
session.Save(article2);
54+
55+
t.Commit();
56+
}
57+
}
58+
59+
protected override void OnTearDown()
60+
{
61+
using (ISession session = sessions.OpenSession())
62+
{
63+
session.Delete("from System.Object");
64+
session.Flush();
65+
}
66+
}
67+
68+
#endregion
69+
70+
[Test]
71+
public void CanEagerFetchRelatedPropertiesUsingSubcriteria()
72+
{
73+
Article result;
74+
using (ISession session = sessions.OpenSession())
75+
{
76+
result = session.CreateCriteria(typeof(Article))
77+
.SetLazyPropertyFetchMode(LazyPropertyFetchMode.Select)
78+
.SetMaxResults(1)
79+
.CreateCriteria("ArticleExtension")
80+
.SetLazyPropertyFetchMode(LazyPropertyFetchMode.Select)
81+
.UniqueResult<Article>();
82+
}
83+
84+
Assert.DoesNotThrow(
85+
delegate
86+
{
87+
Assert.That(String.IsNullOrEmpty(result.Description), Is.False, "Should have been a value in Description");
88+
}, "Should not have thrown an exception accessing the Description property");
89+
90+
Assert.DoesNotThrow(
91+
delegate
92+
{
93+
Assert.That(String.IsNullOrEmpty(result.ArticleExtension.Notes), Is.False, "Should have been a value in ArticleExtension.Notes");
94+
}, "Should not have thrown an exception accessing the ArticleExtension.Notes property");
95+
}
96+
97+
[Test]
98+
public void CanEagerFetchRelatedPropertiesUsingAssociationPath()
99+
{
100+
Article result;
101+
using (ISession session = sessions.OpenSession())
102+
{
103+
result = session.CreateCriteria(typeof(Article))
104+
.SetLazyPropertyFetchMode(LazyPropertyFetchMode.Select)
105+
.SetLazyPropertyFetchMode("ArticleExtension", LazyPropertyFetchMode.Select)
106+
.SetMaxResults(1)
107+
.UniqueResult<Article>();
108+
}
109+
110+
Assert.DoesNotThrow(
111+
delegate
112+
{
113+
Assert.That(String.IsNullOrEmpty(result.Description), Is.False, "Should have been a value in Description");
114+
}, "Should not have thrown an exception accessing the Description property");
115+
116+
Assert.DoesNotThrow(
117+
delegate
118+
{
119+
Assert.That(String.IsNullOrEmpty(result.ArticleExtension.Notes), Is.False, "Should have been a value in ArticleExtension.Notes");
120+
}, "Should not have thrown an exception accessing the ArticleExtension.Notes property");
121+
}
122+
123+
[Test]
124+
public void CanEagerFetchChildAndNotParentProperties()
125+
{
126+
Article result;
127+
using (ISession session = sessions.OpenSession())
128+
{
129+
result = session.CreateCriteria(typeof(Article))
130+
.SetMaxResults(1)
131+
.CreateCriteria("ArticleExtension")
132+
.SetLazyPropertyFetchMode(LazyPropertyFetchMode.Select)
133+
.UniqueResult<Article>();
134+
}
135+
136+
Assert.Throws<LazyInitializationException>(
137+
delegate
138+
{
139+
Assert.That(String.IsNullOrEmpty(result.Description), Is.True);
140+
}, "Should have thrown an exception accessing the Description property");
141+
142+
Assert.DoesNotThrow(
143+
delegate
144+
{
145+
Assert.That(String.IsNullOrEmpty(result.ArticleExtension.Notes), Is.False, "Should have been a value in ArticleExtension.Notes");
146+
}, "Should not have thrown an exception accessing the ArticleExtension.Notes property");
147+
}
148+
149+
[Test]
150+
public void CanEagerFetchParentAndNotChildProperties()
151+
{
152+
Article result;
153+
using (ISession session = sessions.OpenSession())
154+
{
155+
result = session.CreateCriteria(typeof(Article))
156+
.SetMaxResults(1)
157+
.SetLazyPropertyFetchMode(LazyPropertyFetchMode.Select)
158+
.CreateCriteria("ArticleExtension")
159+
.UniqueResult<Article>();
160+
}
161+
162+
Assert.DoesNotThrow(
163+
delegate
164+
{
165+
Assert.That(String.IsNullOrEmpty(result.Description), Is.False);
166+
}, "Should not have thrown an exception accessing the Description property");
167+
168+
Assert.Throws<LazyInitializationException>(
169+
delegate
170+
{
171+
Assert.That(String.IsNullOrEmpty(result.ArticleExtension.Notes), Is.True);
172+
}, "Should have thrown an exception accessing the ArticleExtension.Notes property");
173+
}
174+
}
175+
}

0 commit comments

Comments
 (0)