diff --git a/src/NHibernate.Test/NHSpecificTest/NH3567/DomainClass.cs b/src/NHibernate.Test/NHSpecificTest/NH3567/DomainClass.cs new file mode 100644 index 00000000000..2b81ffe7bd9 --- /dev/null +++ b/src/NHibernate.Test/NHSpecificTest/NH3567/DomainClass.cs @@ -0,0 +1,29 @@ + + +namespace NHibernate.Test.NHSpecificTest.NH3567 +{ + public class Site + { + public virtual int Id { get; set; } + public virtual string Name { get; set; } + + + } + public class Post + { + public virtual int Id { get; set; } + public virtual string Content { get; set; } + public virtual Site Site { get; set; } + + + } + + public class Comment + { + public virtual int Id { get; set; } + public virtual string Content { get; set; } + public virtual Post Post { get; set; } + + } + +} \ No newline at end of file diff --git a/src/NHibernate.Test/NHSpecificTest/NH3567/Mappings.hbm.xml b/src/NHibernate.Test/NHSpecificTest/NH3567/Mappings.hbm.xml new file mode 100644 index 00000000000..00865d09e6e --- /dev/null +++ b/src/NHibernate.Test/NHSpecificTest/NH3567/Mappings.hbm.xml @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/NHibernate.Test/NHSpecificTest/NH3567/NH3567Tests.cs b/src/NHibernate.Test/NHSpecificTest/NH3567/NH3567Tests.cs new file mode 100644 index 00000000000..d3b54c96f19 --- /dev/null +++ b/src/NHibernate.Test/NHSpecificTest/NH3567/NH3567Tests.cs @@ -0,0 +1,107 @@ +using NUnit.Framework; +using NHibernate.Criterion; +using NHibernate.Dialect; + +namespace NHibernate.Test.NHSpecificTest.NH3567 +{ + [TestFixture] + public class NH3567Tests : BugTestCase + { + protected override void OnSetUp() + { + base.OnSetUp(); + using (ISession session = this.OpenSession()) + { + session.BeginTransaction(); + var id = 0; + + var site1 = new Site { Id = ++id, Name = "Site 1" }; + var site2 = new Site { Id = ++id, Name = "Site 1" }; + session.Save(site1); + session.Save(site2); + + + var p1 = new Post { Id = ++id, Content = "Post 1", Site = site1 }; + var p2 = new Post { Id = ++id, Content = "Post 2", Site = site2 }; + + session.Save(p1); + session.Save(p2); + + session.Save(new Comment { Id = ++id, Content = "Comment 1.1", Post = p1 }); + session.Save(new Comment { Id = ++id, Content = "Comment 1.2", Post = p1 }); + session.Save(new Comment { Id = ++id, Content = "Comment 2.1", Post = p2 }); + session.Save(new Comment { Id = ++id, Content = "Comment 2.2", Post = p2 }); + session.Flush(); + session.Transaction.Commit(); + } + } + + protected override void OnTearDown() + { + base.OnTearDown(); + using (ISession session = this.OpenSession()) + { + session.Delete("from Comment"); + session.Delete("from Post"); + session.Delete("from Site"); + session.Flush(); + } + } + + protected override bool AppliesTo(NHibernate.Dialect.Dialect dialect) + { + return dialect as MsSql2005Dialect != null; + } + + [Test] + public void TestFlushModeAuto() + { + using (ISession session = this.OpenSession()) + { + session.FlushMode = FlushMode.Auto; + using (var transaction = session.BeginTransaction()) + { + var post = session.QueryOver().Where(x => x.Content == "Post 1").SingleOrDefault(); + + post.Content = "1"; + + var comments = session.QueryOver().JoinQueryOver(x => x.Post).Where(x => x.Content == "1").List(); + Assert.That(comments.Count, Is.EqualTo(2), "Query over returned something different than 2"); + + post.Content = "I"; + var subquery = DetachedCriteria.For(typeof(Post)) + .Add(Restrictions.Eq("Content", "I")) + .SetProjection(Projections.Id()); + var numberOfComments = + session.CreateCriteria(typeof(Comment)) + .Add(Subqueries.PropertyIn("Post.Id", subquery)) + .List().Count; + Assert.That(numberOfComments, Is.EqualTo(2), "Query with sub-query returned an invalid number of rows."); + + var site = session.Get(1); + site.Name = "Site 3"; + + subquery = DetachedCriteria.For(typeof(Post)) + .SetProjection(Projections.Id()) + .CreateCriteria("Site") + .Add(Restrictions.Eq("Name", "Site 3")); + numberOfComments = + session.CreateCriteria(typeof(Comment)) + .Add(Subqueries.PropertyIn("Post.Id", subquery)) + .List().Count; + + Assert.That(numberOfComments, Is.EqualTo(2), "Query with sub-query returned an invalid number of rows."); + + + transaction.Rollback(); + + } + + } + } + + + } + + +} diff --git a/src/NHibernate.Test/NHibernate.Test.csproj b/src/NHibernate.Test/NHibernate.Test.csproj index c60b89ab659..b1291bdf876 100644 --- a/src/NHibernate.Test/NHibernate.Test.csproj +++ b/src/NHibernate.Test/NHibernate.Test.csproj @@ -693,6 +693,8 @@ + + @@ -3068,6 +3070,7 @@ + diff --git a/src/NHibernate/Loader/Criteria/CriteriaQueryTranslator.cs b/src/NHibernate/Loader/Criteria/CriteriaQueryTranslator.cs index 1c9311e13f5..a828f61c278 100644 --- a/src/NHibernate/Loader/Criteria/CriteriaQueryTranslator.cs +++ b/src/NHibernate/Loader/Criteria/CriteriaQueryTranslator.cs @@ -44,6 +44,9 @@ public class CriteriaQueryTranslator : ICriteriaQuery private readonly ICollection collectedParameterSpecifications; private readonly ICollection namedParameters; + private readonly ISet subQuerySpaces = new HashSet(); + + public CriteriaQueryTranslator(ISessionFactoryImplementor factory, CriteriaImpl criteria, string rootEntityName, string rootSQLAlias, ICriteriaQuery outerQuery) @@ -71,6 +74,7 @@ public CriteriaQueryTranslator(ISessionFactoryImplementor factory, CriteriaImpl CreateCriteriaEntityNameMap(); CreateCriteriaCollectionPersisters(); CreateCriteriaSQLAliasMap(); + CreateSubQuerySpaces(); } [CLSCompliant(false)] // TODO: Why does this cause a problem in 1.1 @@ -92,6 +96,9 @@ public ISet GetQuerySpaces() { result.UnionWith(collectionPersister.CollectionSpaces); } + + result.UnionWith(subQuerySpaces); + return result; } @@ -844,5 +851,24 @@ public string[] GetColumnAliasesUsingProjection(ICriteria subcriteria, string pr } #endregion + + private void CreateSubQuerySpaces() + { + + var subQueries = + rootCriteria.IterateExpressionEntries() + .Select(x => x.Criterion) + .OfType() + .Select(x => x.Criteria) + .OfType(); + + foreach (var criteriaImpl in subQueries) + { + //The RootSqlAlias is not relevant, since we're only retreiving the query spaces + var translator = new CriteriaQueryTranslator(sessionFactory, criteriaImpl, criteriaImpl.EntityOrClassName, RootSqlAlias); + subQuerySpaces.UnionWith(translator.GetQuerySpaces()); + } + + } } -} +} \ No newline at end of file