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/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.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/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]) { diff --git a/src/NHibernate/Mapping/ByCode/ModelMapper.cs b/src/NHibernate/Mapping/ByCode/ModelMapper.cs index 90ae09d4ab8..dc233efe8ea 100644 --- a/src/NHibernate/Mapping/ByCode/ModelMapper.cs +++ b/src/NHibernate/Mapping/ByCode/ModelMapper.cs @@ -1280,9 +1280,22 @@ protected virtual ICollectionElementRelationMapper DetermineCollectionElementRel { return new OneToManyRelationMapper(propertyPath, ownerType, collectionElementType, modelInspector, customizerHolder, this); } - if (modelInspector.IsManyToMany(property)) + //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) { - 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)) {