diff --git a/src/NHibernate.Test/Async/LazyProperty/LazyPropertyFixture.cs b/src/NHibernate.Test/Async/LazyProperty/LazyPropertyFixture.cs index cce9ce89adf..097ee70b746 100644 --- a/src/NHibernate.Test/Async/LazyProperty/LazyPropertyFixture.cs +++ b/src/NHibernate.Test/Async/LazyProperty/LazyPropertyFixture.cs @@ -9,9 +9,11 @@ using System.Collections; +using System.Linq; using NHibernate.Intercept; using NHibernate.Tuple.Entity; using NUnit.Framework; +using NHibernate.Linq; namespace NHibernate.Test.LazyProperty { @@ -68,7 +70,7 @@ protected override void OnTearDown() using (var s = OpenSession()) using (var tx = s.BeginTransaction()) { - Assert.That(s.CreateSQLQuery("delete from Book").ExecuteUpdate(), Is.EqualTo(1)); + s.CreateQuery("delete from Book").ExecuteUpdate(); tx.Commit(); } } @@ -137,14 +139,25 @@ public async Task CanGetValueForNonLazyPropertyAsync() public async Task CanLoadAndSaveObjectInDifferentSessionsAsync() { Book book; + int bookCount; using (ISession s = OpenSession()) { + bookCount = await (s.Query().CountAsync()); book = await (s.GetAsync(1)); } + book.Name += " updated"; + using (ISession s = OpenSession()) { await (s.MergeAsync(book)); + await (s.FlushAsync()); + } + + using (ISession s = OpenSession()) + { + Assert.That(await (s.Query().CountAsync()), Is.EqualTo(bookCount)); + Assert.That((await (s.GetAsync(1))).Name, Is.EqualTo(book.Name)); } } @@ -171,5 +184,37 @@ public async Task CanUpdateNonLazyWithoutLoadingLazyPropertyAsync() Assert.That(book.FieldInterceptor, Is.EqualTo("Why not that name?updated")); } } + + [Test] + public async Task CanMergeTransientWithLazyPropertyAsync() + { + using (ISession s = OpenSession()) + { + var book = await (s.GetAsync(2)); + Assert.That(book, Is.Null); + } + + using (ISession s = OpenSession()) + using (var tx = s.BeginTransaction()) + { + var book = new Book + { + Name = "some name two", + Id = 2, + ALotOfText = "a lot of text two..." + }; + // This should insert a new entity. + await (s.MergeAsync(book)); + await (tx.CommitAsync()); + } + + using (ISession s = OpenSession()) + { + var book = await (s.GetAsync(2)); + Assert.That(book, Is.Not.Null); + Assert.That(book.Name, Is.EqualTo("some name two")); + Assert.That(book.ALotOfText, Is.EqualTo("a lot of text two...")); + } + } } } diff --git a/src/NHibernate.Test/LazyProperty/LazyPropertyFixture.cs b/src/NHibernate.Test/LazyProperty/LazyPropertyFixture.cs index 4d798386c40..d57c56946a5 100644 --- a/src/NHibernate.Test/LazyProperty/LazyPropertyFixture.cs +++ b/src/NHibernate.Test/LazyProperty/LazyPropertyFixture.cs @@ -1,4 +1,5 @@ using System.Collections; +using System.Linq; using NHibernate.Intercept; using NHibernate.Tuple.Entity; using NUnit.Framework; @@ -57,7 +58,7 @@ protected override void OnTearDown() using (var s = OpenSession()) using (var tx = s.BeginTransaction()) { - Assert.That(s.CreateSQLQuery("delete from Book").ExecuteUpdate(), Is.EqualTo(1)); + s.CreateQuery("delete from Book").ExecuteUpdate(); tx.Commit(); } } @@ -132,14 +133,25 @@ public void CanGetValueForNonLazyProperty() public void CanLoadAndSaveObjectInDifferentSessions() { Book book; + int bookCount; using (ISession s = OpenSession()) { + bookCount = s.Query().Count(); book = s.Get(1); } + book.Name += " updated"; + using (ISession s = OpenSession()) { s.Merge(book); + s.Flush(); + } + + using (ISession s = OpenSession()) + { + Assert.That(s.Query().Count(), Is.EqualTo(bookCount)); + Assert.That(s.Get(1).Name, Is.EqualTo(book.Name)); } } @@ -166,5 +178,37 @@ public void CanUpdateNonLazyWithoutLoadingLazyProperty() Assert.That(book.FieldInterceptor, Is.EqualTo("Why not that name?updated")); } } + + [Test] + public void CanMergeTransientWithLazyProperty() + { + using (ISession s = OpenSession()) + { + var book = s.Get(2); + Assert.That(book, Is.Null); + } + + using (ISession s = OpenSession()) + using (var tx = s.BeginTransaction()) + { + var book = new Book + { + Name = "some name two", + Id = 2, + ALotOfText = "a lot of text two..." + }; + // This should insert a new entity. + s.Merge(book); + tx.Commit(); + } + + using (ISession s = OpenSession()) + { + var book = s.Get(2); + Assert.That(book, Is.Not.Null); + Assert.That(book.Name, Is.EqualTo("some name two")); + Assert.That(book.ALotOfText, Is.EqualTo("a lot of text two...")); + } + } } } diff --git a/src/NHibernate/Intercept/DefaultDynamicLazyFieldInterceptor.cs b/src/NHibernate/Intercept/DefaultDynamicLazyFieldInterceptor.cs index 7c0f42b68d0..5e4ec4bdcbc 100644 --- a/src/NHibernate/Intercept/DefaultDynamicLazyFieldInterceptor.cs +++ b/src/NHibernate/Intercept/DefaultDynamicLazyFieldInterceptor.cs @@ -12,16 +12,15 @@ public class DefaultDynamicLazyFieldInterceptor : IFieldInterceptorAccessor, Pro public object Intercept(InvocationInfo info) { - var methodName = info.TargetMethod.Name; - if (FieldInterceptor != null) + if (ReflectHelper.IsPropertyGet(info.TargetMethod)) { - if (ReflectHelper.IsPropertyGet(info.TargetMethod)) + if (IsGetFieldInterceptorCall(info.TargetMethod)) { - if (IsGetFieldInterceptorCall(methodName, info.TargetMethod)) - { - return FieldInterceptor; - } + return FieldInterceptor; + } + if (FieldInterceptor != null) + { object propValue = info.InvokeMethodOnTarget(); var result = FieldInterceptor.Intercept(info.Target, ReflectHelper.GetPropertyName(info.TargetMethod), propValue); @@ -31,37 +30,33 @@ public object Intercept(InvocationInfo info) return result; } } - else if (ReflectHelper.IsPropertySet(info.TargetMethod)) - { - if (IsSetFieldInterceptorCall(methodName, info.TargetMethod)) - { - FieldInterceptor = (IFieldInterceptor)info.Arguments[0]; - return null; - } - FieldInterceptor.MarkDirty(); - FieldInterceptor.Intercept(info.Target, ReflectHelper.GetPropertyName(info.TargetMethod), info.Arguments[0]); - } } - else + else if (ReflectHelper.IsPropertySet(info.TargetMethod)) { - if (IsSetFieldInterceptorCall(methodName, info.TargetMethod)) + if (IsSetFieldInterceptorCall(info.TargetMethod)) { - FieldInterceptor = (IFieldInterceptor)info.Arguments[0]; + FieldInterceptor = (IFieldInterceptor) info.Arguments[0]; return null; } + + if (FieldInterceptor != null) + { + FieldInterceptor.MarkDirty(); + FieldInterceptor.Intercept(info.Target, ReflectHelper.GetPropertyName(info.TargetMethod), info.Arguments[0]); + } } return info.InvokeMethodOnTarget(); } - private static bool IsGetFieldInterceptorCall(string methodName, MethodInfo targetMethod) + private static bool IsGetFieldInterceptorCall(MethodInfo targetMethod) { - return "get_FieldInterceptor".Equals(methodName) && targetMethod.DeclaringType == typeof(IFieldInterceptorAccessor); + return string.Equals("get_FieldInterceptor", targetMethod.Name, StringComparison.Ordinal) && targetMethod.DeclaringType == typeof(IFieldInterceptorAccessor); } - private static bool IsSetFieldInterceptorCall(string methodName, MethodInfo targetMethod) + private static bool IsSetFieldInterceptorCall(MethodInfo targetMethod) { - return "set_FieldInterceptor".Equals(methodName) && targetMethod.DeclaringType == typeof(IFieldInterceptorAccessor); + return string.Equals("set_FieldInterceptor", targetMethod.Name, StringComparison.Ordinal) && targetMethod.DeclaringType == typeof(IFieldInterceptorAccessor); } } }