From dfe84cefa4652e7a8c7074d6de671ad5eecaeec9 Mon Sep 17 00:00:00 2001 From: Ricardo Peres Date: Mon, 1 Sep 2014 00:27:31 +0100 Subject: [PATCH 1/6] NH-3667 NH-3102 --- .../IntegrationTests/NH3667/MapFixture.cs | 459 ++++++++++++++++++ .../IntegrationTests/NH3667/Model.cs | 73 +++ src/NHibernate.Test/NHibernate.Test.csproj | 4 +- src/NHibernate/Mapping/ByCode/ModelMapper.cs | 3 +- 4 files changed, 537 insertions(+), 2 deletions(-) create mode 100644 src/NHibernate.Test/MappingByCode/IntegrationTests/NH3667/MapFixture.cs create mode 100644 src/NHibernate.Test/MappingByCode/IntegrationTests/NH3667/Model.cs diff --git a/src/NHibernate.Test/MappingByCode/IntegrationTests/NH3667/MapFixture.cs b/src/NHibernate.Test/MappingByCode/IntegrationTests/NH3667/MapFixture.cs new file mode 100644 index 00000000000..11b47639aab --- /dev/null +++ b/src/NHibernate.Test/MappingByCode/IntegrationTests/NH3667/MapFixture.cs @@ -0,0 +1,459 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using NHibernate.Cfg; +using NHibernate.Dialect; +using NHibernate.Mapping.ByCode; +using NUnit.Framework; + +namespace NHibernate.Test.MappingByCode.IntegrationTests.NH3667 +{ + [TestFixture] + public class MapFixture + { + [Test] + public void TestMapElementElement() + { + var cfg = new Configuration().Configure(); + var mapper = new ModelMapper(); + + mapper.Class(c => + { + c.Lazy(false); + c.Id(id => id.Id, id => + { + id.Generator(Generators.Identity); + }); + + c.Map(m => m.Map, col => + { + col.Table("element_element"); + col.Key(k => k.Column("id")); + }, key => + { + key.Element(e => + { + e.Column("key"); + }); + }, element => + { + element.Element(e => + { + e.Column("element"); + }); + }); + }); + + cfg.AddMapping(mapper.CompileMappingForAllExplicitlyAddedEntities()); + + var script = cfg.GenerateSchemaCreationScript(new MsSql2012Dialect()); + + Assert.False(script.Any(x => x.Contains("idx"))); + } + + [Test] + public void TestMapEntityEntity() + { + var cfg = new Configuration().Configure(); + var mapper = new ModelMapper(); + + mapper.Class(c => + { + c.Lazy(false); + c.Id(id => id.Id, id => + { + id.Generator(Generators.Identity); + }); + + c.Map(m => m.Map, col => + { + col.Table("entity_entity"); + col.Key(k => k.Column("id")); + }, key => + { + key.ManyToMany(e => + { + e.Column("key"); + }); + }, element => + { + element.ManyToMany(e => + { + e.Column("element"); + }); + }); + }); + + mapper.Class(c => + { + c.Lazy(false); + c.Id(id => id.A, id => + { + id.Generator(Generators.Identity); + }); + c.Property(p => p.B); + }); + + cfg.AddMapping(mapper.CompileMappingForAllExplicitlyAddedEntities()); + + var script = cfg.GenerateSchemaCreationScript(new MsSql2012Dialect()); + + Assert.False(script.Any(x => x.Contains("idx"))); + } + + [Test] + public void TestMapEntityElement() + { + var cfg = new Configuration().Configure(); + var mapper = new ModelMapper(); + + mapper.Class(c => + { + c.Lazy(false); + c.Id(id => id.Id, id => + { + id.Generator(Generators.Identity); + }); + + c.Map(m => m.Map, col => + { + col.Table("entity_element"); + col.Key(k => k.Column("id")); + }, key => + { + key.ManyToMany(e => + { + e.Column("key"); + }); + }, element => + { + element.Element(e => + { + e.Column("element"); + }); + }); + }); + + mapper.Class(c => + { + c.Lazy(false); + c.Id(id => id.A, id => + { + id.Generator(Generators.Identity); + }); + c.Property(p => p.B); + }); + + cfg.AddMapping(mapper.CompileMappingForAllExplicitlyAddedEntities()); + + var script = cfg.GenerateSchemaCreationScript(new MsSql2012Dialect()); + + Assert.False(script.Any(x => x.Contains("idx"))); + } + + [Test] + public void TestMapElementEntity() + { + var cfg = new Configuration().Configure(); + var mapper = new ModelMapper(); + + mapper.Class(c => + { + c.Lazy(false); + c.Id(id => id.Id, id => + { + id.Generator(Generators.Identity); + }); + + c.Map(m => m.Map, col => + { + col.Table("element_entity"); + col.Key(k => k.Column("id")); + }, key => + { + key.Element(e => + { + e.Column("key"); + }); + }, element => + { + element.ManyToMany(e => + { + e.Column("element"); + }); + }); + }); + + mapper.Class(c => + { + c.Lazy(false); + c.Id(id => id.A, id => + { + id.Generator(Generators.Identity); + }); + c.Property(p => p.B); + }); + + cfg.AddMapping(mapper.CompileMappingForAllExplicitlyAddedEntities()); + + var script = cfg.GenerateSchemaCreationScript(new MsSql2012Dialect()); + + Assert.False(script.Any(x => x.Contains("idx"))); + } + + [Test] + public void TestMapEntityComponent() + { + var cfg = new Configuration().Configure(); + var mapper = new ModelMapper(); + + mapper.Class(c => + { + c.Lazy(false); + c.Id(id => id.Id, id => + { + id.Generator(Generators.Identity); + }); + + c.Map(m => m.Map, col => + { + col.Table("entity_component"); + col.Key(k => k.Column("id")); + }, key => + { + key.ManyToMany(e => + { + e.Column("key"); + }); + }, element => + { + element.Component(cmp => + { + cmp.Class(); + }); + }); + }); + + mapper.Component(c => + { + c.Property(p => p.A); + c.Property(p => p.B); + }); + + mapper.Class(c => + { + c.Lazy(false); + c.Id(id => id.A, id => + { + id.Generator(Generators.Identity); + }); + c.Property(p => p.B); + }); + + cfg.AddMapping(mapper.CompileMappingForAllExplicitlyAddedEntities()); + + var script = cfg.GenerateSchemaCreationScript(new MsSql2012Dialect()); + + Assert.False(script.Any(x => x.Contains("idx"))); + } + + [Test] + public void TestMapElementComponent() + { + var cfg = new Configuration().Configure(); + var mapper = new ModelMapper(); + + mapper.Class(c => + { + c.Lazy(false); + c.Id(id => id.Id, id => + { + id.Generator(Generators.Identity); + }); + + c.Map(m => m.Map, col => + { + col.Table("element_component"); + col.Key(k => k.Column("id")); + }, key => + { + key.Element(e => + { + e.Column("key"); + }); + }, element => + { + element.Component(cmp => + { + cmp.Class(); + }); + }); + }); + + mapper.Component(c => + { + c.Property(p => p.A); + c.Property(p => p.B); + }); + + cfg.AddMapping(mapper.CompileMappingForAllExplicitlyAddedEntities()); + + var script = cfg.GenerateSchemaCreationScript(new MsSql2012Dialect()); + + Assert.False(script.Any(x => x.Contains("idx"))); + } + + [Test] + public void TestMapComponentComponent() + { + var cfg = new Configuration().Configure(); + var mapper = new ModelMapper(); + + mapper.Class(c => + { + c.Lazy(false); + c.Id(id => id.Id, id => + { + id.Generator(Generators.Identity); + }); + + c.Map(m => m.Map, col => + { + col.Table("component_component"); + col.Key(k => k.Column("id")); + }, key => + { + key.Component(cmp => + { + cmp.Property(p => p.A); + cmp.Property(p => p.B); + }); + }, element => + { + element.Component(cmp => + { + cmp.Class(); + }); + }); + }); + + mapper.Component(c => + { + c.Property(p => p.A); + c.Property(p => p.B); + }); + + cfg.AddMapping(mapper.CompileMappingForAllExplicitlyAddedEntities()); + + var script = cfg.GenerateSchemaCreationScript(new MsSql2012Dialect()); + + Assert.False(script.Any(x => x.Contains("idx"))); + } + + [Test] + public void TestMapComponentElement() + { + var cfg = new Configuration().Configure(); + var mapper = new ModelMapper(); + + mapper.Class(c => + { + c.Lazy(false); + c.Id(id => id.Id, id => + { + id.Generator(Generators.Identity); + }); + + c.Map(m => m.Map, col => + { + col.Table("component_element"); + col.Key(k => k.Column("id")); + }, key => + { + key.Component(cmp => + { + cmp.Property(p => p.A); + cmp.Property(p => p.B); + }); + }, element => + { + element.Element(e => + { + e.Column("element"); + }); + }); + }); + + mapper.Component(c => + { + c.Property(p => p.A); + c.Property(p => p.B); + }); + + cfg.AddMapping(mapper.CompileMappingForAllExplicitlyAddedEntities()); + + var script = cfg.GenerateSchemaCreationScript(new MsSql2012Dialect()); + + Assert.False(script.Any(x => x.Contains("idx"))); + } + + //OK + [Test] + public void TestMapComponentEntity() + { + var cfg = new Configuration().Configure(); + var mapper = new ModelMapper(); + + mapper.Class(c => + { + c.Lazy(false); + c.Id(id => id.Id, id => + { + id.Generator(Generators.Identity); + }); + + c.Map(m => m.Map, col => + { + col.Table("component_entity"); + col.Key(k => k.Column("id")); + }, key => + { + key.Component(cmp => + { + cmp.Property(p => p.A); + cmp.Property(p => p.B); + }); + }, element => + { + element.ManyToMany(e => + { + e.Column("element"); + }); + }); + }); + + mapper.Component(c => + { + c.Property(p => p.A); + c.Property(p => p.B); + }); + + mapper.Class(c => + { + c.Lazy(false); + c.Id(id => id.A, id => + { + id.Generator(Generators.Identity); + }); + c.Property(p => p.B); + }); + + cfg.AddMapping(mapper.CompileMappingForAllExplicitlyAddedEntities()); + + var script = cfg.GenerateSchemaCreationScript(new MsSql2012Dialect()); + + Assert.False(script.Any(x => x.Contains("idx"))); + } + } +} diff --git a/src/NHibernate.Test/MappingByCode/IntegrationTests/NH3667/Model.cs b/src/NHibernate.Test/MappingByCode/IntegrationTests/NH3667/Model.cs new file mode 100644 index 00000000000..400f2bd8498 --- /dev/null +++ b/src/NHibernate.Test/MappingByCode/IntegrationTests/NH3667/Model.cs @@ -0,0 +1,73 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace NHibernate.Test.MappingByCode.IntegrationTests.NH3667 +{ + public class Entity + { + public int A { get; set; } + public string B { get; set; } + } + + public class Component + { + public int A { get; set; } + public int B { get; set; } + } + + public class ClassWithMapEntityElement + { + public int Id { get; set; } + public IDictionary Map { get; set; } + } + + public class ClassWithMapElementComponent + { + public int Id { get; set; } + public IDictionary Map { get; set; } + } + + public class ClassWithMapEntityComponent + { + public int Id { get; set; } + public IDictionary Map { get; set; } + } + + public class ClassWithMapElementEntity + { + public int Id { get; set; } + public IDictionary Map { get; set; } + } + + public class ClassWithMapComponentEntity + { + public int Id { get; set; } + public IDictionary Map { get; set; } + } + + public class ClassWithMapComponentElement + { + public int Id { get; set; } + public IDictionary Map { get; set; } + } + + public class ClassWithMapComponentComponent + { + public int Id { get; set; } + public IDictionary Map { get; set; } + } + + public class ClassWithMapEntityEntity + { + public int Id { get; set; } + public IDictionary Map { get; set; } + } + + public class ClassWithMapElementElement + { + public int Id { get; set; } + public IDictionary Map { get; set; } + } +} diff --git a/src/NHibernate.Test/NHibernate.Test.csproj b/src/NHibernate.Test/NHibernate.Test.csproj index a8d325494c7..c627b769e36 100644 --- a/src/NHibernate.Test/NHibernate.Test.csproj +++ b/src/NHibernate.Test/NHibernate.Test.csproj @@ -607,6 +607,8 @@ + + @@ -3630,4 +3632,4 @@ if exist hibernate.cfg.xml (del hibernate.cfg.xml) if exist "$(ProjectDir)hibernate.cfg.xml" (copy "$(ProjectDir)hibernate.cfg.xml" "hibernate.cfg.xml") copy /y "..\..\..\NHibernate.DomainModel\ABC.hbm.xml" "ABC.hbm.xml" - + \ No newline at end of file diff --git a/src/NHibernate/Mapping/ByCode/ModelMapper.cs b/src/NHibernate/Mapping/ByCode/ModelMapper.cs index 90ae09d4ab8..42967a72df4 100644 --- a/src/NHibernate/Mapping/ByCode/ModelMapper.cs +++ b/src/NHibernate/Mapping/ByCode/ModelMapper.cs @@ -1280,7 +1280,8 @@ protected virtual ICollectionElementRelationMapper DetermineCollectionElementRel { return new OneToManyRelationMapper(propertyPath, ownerType, collectionElementType, modelInspector, customizerHolder, this); } - if (modelInspector.IsManyToMany(property)) + //NH-3667 & NH-3102 + if ((modelInspector.IsManyToMany(property)) && (modelInspector.IsEntity(property.GetPropertyOrFieldType().GetGenericArguments()[1]))) { return new ManyToManyRelationMapper(propertyPath, customizerHolder, this); } From 38bbcd57629b8cdf7defdfac856f1676b8013953 Mon Sep 17 00:00:00 2001 From: Ricardo Peres Date: Mon, 1 Sep 2014 11:32:17 +0100 Subject: [PATCH 2/6] Fix --- src/NHibernate/Mapping/ByCode/ModelMapper.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/NHibernate/Mapping/ByCode/ModelMapper.cs b/src/NHibernate/Mapping/ByCode/ModelMapper.cs index 42967a72df4..3d00b367149 100644 --- a/src/NHibernate/Mapping/ByCode/ModelMapper.cs +++ b/src/NHibernate/Mapping/ByCode/ModelMapper.cs @@ -1281,7 +1281,7 @@ protected virtual ICollectionElementRelationMapper DetermineCollectionElementRel return new OneToManyRelationMapper(propertyPath, ownerType, collectionElementType, modelInspector, customizerHolder, this); } //NH-3667 & NH-3102 - if ((modelInspector.IsManyToMany(property)) && (modelInspector.IsEntity(property.GetPropertyOrFieldType().GetGenericArguments()[1]))) + if ((modelInspector.IsManyToMany(property)) && ((property.GetPropertyOrFieldType().GetGenericArguments().Length > 1) && (modelInspector.IsEntity(property.GetPropertyOrFieldType().GetGenericArguments()[1])))) { return new ManyToManyRelationMapper(propertyPath, customizerHolder, this); } From a02e476ad561414d39ee1d6eab085bd07ce927a6 Mon Sep 17 00:00:00 2001 From: Ricardo Peres Date: Mon, 1 Sep 2014 11:58:04 +0100 Subject: [PATCH 3/6] Corrections --- src/NHibernate/Mapping/ByCode/ModelMapper.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/NHibernate/Mapping/ByCode/ModelMapper.cs b/src/NHibernate/Mapping/ByCode/ModelMapper.cs index 3d00b367149..4539f303c9a 100644 --- a/src/NHibernate/Mapping/ByCode/ModelMapper.cs +++ b/src/NHibernate/Mapping/ByCode/ModelMapper.cs @@ -1281,7 +1281,7 @@ protected virtual ICollectionElementRelationMapper DetermineCollectionElementRel return new OneToManyRelationMapper(propertyPath, ownerType, collectionElementType, modelInspector, customizerHolder, this); } //NH-3667 & NH-3102 - if ((modelInspector.IsManyToMany(property)) && ((property.GetPropertyOrFieldType().GetGenericArguments().Length > 1) && (modelInspector.IsEntity(property.GetPropertyOrFieldType().GetGenericArguments()[1])))) + if ((modelInspector.IsManyToMany(property)) && ((property.GetPropertyOrFieldType().GetGenericArguments().Length < 2) || ((property.GetPropertyOrFieldType().GetGenericArguments().Length > 1) && (modelInspector.IsEntity(property.GetPropertyOrFieldType().GetGenericArguments()[1]))))) { return new ManyToManyRelationMapper(propertyPath, customizerHolder, this); } From d994b717d39ed208d00ffcf096ed87bb7805d469 Mon Sep 17 00:00:00 2001 From: Ricardo Peres Date: Tue, 2 Sep 2014 22:16:39 +0100 Subject: [PATCH 4/6] Split long line as requested Added comment --- src/NHibernate/Mapping/ByCode/ModelMapper.cs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/NHibernate/Mapping/ByCode/ModelMapper.cs b/src/NHibernate/Mapping/ByCode/ModelMapper.cs index 4539f303c9a..693ad40aad0 100644 --- a/src/NHibernate/Mapping/ByCode/ModelMapper.cs +++ b/src/NHibernate/Mapping/ByCode/ModelMapper.cs @@ -1281,7 +1281,10 @@ protected virtual ICollectionElementRelationMapper DetermineCollectionElementRel return new OneToManyRelationMapper(propertyPath, ownerType, collectionElementType, modelInspector, customizerHolder, this); } //NH-3667 & NH-3102 - if ((modelInspector.IsManyToMany(property)) && ((property.GetPropertyOrFieldType().GetGenericArguments().Length < 2) || ((property.GetPropertyOrFieldType().GetGenericArguments().Length > 1) && (modelInspector.IsEntity(property.GetPropertyOrFieldType().GetGenericArguments()[1]))))) + //check if property is really a many-to-many: as detected by modelInspector.IsManyToMany and also the collection type is an entity + if ((modelInspector.IsManyToMany(property) == true) && + ((property.GetPropertyOrFieldType().GetGenericArguments().Length < 2) || + ((property.GetPropertyOrFieldType().GetGenericArguments().Length > 1) && (modelInspector.IsEntity(property.GetPropertyOrFieldType().GetGenericArguments()[1])) == true))) { return new ManyToManyRelationMapper(propertyPath, customizerHolder, this); } From 63ecf392d5ebd3f4db582af4326f0befad9ae8aa Mon Sep 17 00:00:00 2001 From: Ricardo Peres Date: Wed, 3 Sep 2014 00:07:29 +0100 Subject: [PATCH 5/6] Minor optimization and code cleaning --- src/NHibernate/Mapping/ByCode/ModelMapper.cs | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/src/NHibernate/Mapping/ByCode/ModelMapper.cs b/src/NHibernate/Mapping/ByCode/ModelMapper.cs index 693ad40aad0..dc233efe8ea 100644 --- a/src/NHibernate/Mapping/ByCode/ModelMapper.cs +++ b/src/NHibernate/Mapping/ByCode/ModelMapper.cs @@ -1282,11 +1282,20 @@ protected virtual ICollectionElementRelationMapper DetermineCollectionElementRel } //NH-3667 & NH-3102 //check if property is really a many-to-many: as detected by modelInspector.IsManyToMany and also the collection type is an entity - if ((modelInspector.IsManyToMany(property) == true) && - ((property.GetPropertyOrFieldType().GetGenericArguments().Length < 2) || - ((property.GetPropertyOrFieldType().GetGenericArguments().Length > 1) && (modelInspector.IsEntity(property.GetPropertyOrFieldType().GetGenericArguments()[1])) == true))) + if (modelInspector.IsManyToMany(property) == true) { - return new ManyToManyRelationMapper(propertyPath, customizerHolder, this); + if (property.GetPropertyOrFieldType().IsGenericCollection() == true) + { + var args = property.GetPropertyOrFieldType().GetGenericArguments(); + + if ((args.Length < 2) || (args.Length > 1)) + { + if (modelInspector.IsEntity(args[1]) == true) + { + return new ManyToManyRelationMapper(propertyPath, customizerHolder, this); + } + } + } } if (modelInspector.IsComponent(collectionElementType)) { From 87ce4514ad90ac420d474ebda8ab8066a1f1bec1 Mon Sep 17 00:00:00 2001 From: Ricardo Peres Date: Wed, 3 Sep 2014 00:44:45 +0100 Subject: [PATCH 6/6] Fix with unit tests --- .../Futures/FutureCriteriaFixture.cs | 15 +++++++++++++++ .../Futures/FutureQueryFixture.cs | 17 ++++++++++++++++- .../Futures/FutureQueryOverFixture.cs | 15 +++++++++++++++ .../NHSpecificTest/Futures/LinqFutureFixture.cs | 14 ++++++++++++++ src/NHibernate/Impl/MultiCriteriaImpl.cs | 3 ++- 5 files changed, 62 insertions(+), 2 deletions(-) diff --git a/src/NHibernate.Test/NHSpecificTest/Futures/FutureCriteriaFixture.cs b/src/NHibernate.Test/NHSpecificTest/Futures/FutureCriteriaFixture.cs index 12f688718b1..407171b759e 100644 --- a/src/NHibernate.Test/NHSpecificTest/Futures/FutureCriteriaFixture.cs +++ b/src/NHibernate.Test/NHSpecificTest/Futures/FutureCriteriaFixture.cs @@ -1,3 +1,4 @@ +using System.Linq; using NHibernate.Criterion; using NHibernate.Impl; using NUnit.Framework; @@ -7,6 +8,20 @@ namespace NHibernate.Test.NHSpecificTest.Futures [TestFixture] public class FutureCriteriaFixture : FutureFixture { + [Test] + public void DefaultReadOnlyTest() + { + //NH-3575 + using (var s = sessions.OpenSession()) + { + s.DefaultReadOnly = true; + + var persons = s.CreateCriteria(typeof(Person)).Future(); + + Assert.IsTrue(persons.All(p => s.IsReadOnly(p))); + } + } + [Test] public void CanUseFutureCriteria() { diff --git a/src/NHibernate.Test/NHSpecificTest/Futures/FutureQueryFixture.cs b/src/NHibernate.Test/NHSpecificTest/Futures/FutureQueryFixture.cs index 32dfae19a59..4a23fbb43e0 100644 --- a/src/NHibernate.Test/NHSpecificTest/Futures/FutureQueryFixture.cs +++ b/src/NHibernate.Test/NHSpecificTest/Futures/FutureQueryFixture.cs @@ -1,4 +1,5 @@ -using NHibernate.Driver; +using System.Linq; +using NHibernate.Driver; using NHibernate.Impl; using NUnit.Framework; @@ -9,6 +10,20 @@ namespace NHibernate.Test.NHSpecificTest.Futures [TestFixture] public class FutureQueryFixture : FutureFixture { + [Test] + public void DefaultReadOnlyTest() + { + //NH-3575 + using (var s = sessions.OpenSession()) + { + s.DefaultReadOnly = true; + + var persons = s.CreateQuery("from Person").Future(); + + Assert.IsTrue(persons.All(p => s.IsReadOnly(p))); + } + } + [Test] public void CanUseFutureQuery() { diff --git a/src/NHibernate.Test/NHSpecificTest/Futures/FutureQueryOverFixture.cs b/src/NHibernate.Test/NHSpecificTest/Futures/FutureQueryOverFixture.cs index 1185a29ed2d..f0300787453 100644 --- a/src/NHibernate.Test/NHSpecificTest/Futures/FutureQueryOverFixture.cs +++ b/src/NHibernate.Test/NHSpecificTest/Futures/FutureQueryOverFixture.cs @@ -1,3 +1,4 @@ +using System.Linq; using NHibernate.Criterion; using NHibernate.Impl; using NUnit.Framework; @@ -30,6 +31,20 @@ protected override void OnTearDown() } } + [Test] + public void DefaultReadOnlyTest() + { + //NH-3575 + using (var s = sessions.OpenSession()) + { + s.DefaultReadOnly = true; + + var persons = s.QueryOver().Future(); + + Assert.IsTrue(persons.All(p => s.IsReadOnly(p))); + } + } + [Test] public void CanUseFutureCriteria() { diff --git a/src/NHibernate.Test/NHSpecificTest/Futures/LinqFutureFixture.cs b/src/NHibernate.Test/NHSpecificTest/Futures/LinqFutureFixture.cs index 4d7230bdbb4..614d23a3439 100644 --- a/src/NHibernate.Test/NHSpecificTest/Futures/LinqFutureFixture.cs +++ b/src/NHibernate.Test/NHSpecificTest/Futures/LinqFutureFixture.cs @@ -8,6 +8,20 @@ namespace NHibernate.Test.NHSpecificTest.Futures [TestFixture] public class LinqFutureFixture : FutureFixture { + [Test] + public void DefaultReadOnlyTest() + { + //NH-3575 + using (var s = sessions.OpenSession()) + { + s.DefaultReadOnly = true; + + var persons = s.Query().ToFuture(); + + Assert.IsTrue(persons.All(p => s.IsReadOnly(p))); + } + } + [Test] public void CoalesceShouldWorkForFutures() { diff --git a/src/NHibernate/Impl/MultiCriteriaImpl.cs b/src/NHibernate/Impl/MultiCriteriaImpl.cs index 85b8df719e8..02498de32d1 100644 --- a/src/NHibernate/Impl/MultiCriteriaImpl.cs +++ b/src/NHibernate/Impl/MultiCriteriaImpl.cs @@ -247,7 +247,8 @@ private void GetResultsFromDatabase(IList results) for (int i = 0; i < loaders.Count; i++) { CriteriaLoader loader = loaders[i]; - loader.InitializeEntitiesAndCollections(hydratedObjects[i], reader, session, false); + //NH-3575 + loader.InitializeEntitiesAndCollections(hydratedObjects[i], reader, session, session.DefaultReadOnly); if (createSubselects[i]) {