From 86a60866e8faa7b3f7a922674aa6eff27e55f4e8 Mon Sep 17 00:00:00 2001 From: offan Date: Thu, 24 Jan 2019 19:31:00 +0300 Subject: [PATCH 1/5] NHTest --- src/NHibernate.Test/LazyProperty/Book.cs | 6 ++- .../LazyProperty/LazyPropertyFixture.cs | 45 +++++++++++++++++++ .../LazyProperty/Mappings.hbm.xml | 14 ++++++ src/NHibernate.Test/LazyProperty/Word.cs | 9 ++++ 4 files changed, 73 insertions(+), 1 deletion(-) create mode 100644 src/NHibernate.Test/LazyProperty/Word.cs diff --git a/src/NHibernate.Test/LazyProperty/Book.cs b/src/NHibernate.Test/LazyProperty/Book.cs index c4fdf9c5639..546df8a248b 100644 --- a/src/NHibernate.Test/LazyProperty/Book.cs +++ b/src/NHibernate.Test/LazyProperty/Book.cs @@ -1,4 +1,6 @@ -namespace NHibernate.Test.LazyProperty +using System.Collections.Generic; + +namespace NHibernate.Test.LazyProperty { public class Book { @@ -16,5 +18,7 @@ public virtual string ALotOfText public virtual byte[] Image { get; set; } public virtual string FieldInterceptor { get; set; } + + public virtual IList Words { get; set; } } } diff --git a/src/NHibernate.Test/LazyProperty/LazyPropertyFixture.cs b/src/NHibernate.Test/LazyProperty/LazyPropertyFixture.cs index c70e46ed224..198a2dbeb46 100644 --- a/src/NHibernate.Test/LazyProperty/LazyPropertyFixture.cs +++ b/src/NHibernate.Test/LazyProperty/LazyPropertyFixture.cs @@ -1,4 +1,5 @@ using System.Collections; +using System.Collections.Generic; using System.Linq; using NHibernate.Cfg; using NHibernate.Intercept; @@ -338,5 +339,49 @@ public void CacheShouldNotContainLazyProperties() Assert.That(NHibernateUtil.IsPropertyInitialized(book, "ALotOfText"), Is.False); Assert.That(NHibernateUtil.IsPropertyInitialized(book, "Image"), Is.False); } + + [Test] + public void CanMergeTransientWithLazyPropertyInCollenction() + { + using (ISession s = OpenSession()) + using (var tx = s.BeginTransaction()) + { + var book = new Book + { + Name = "some name two", + Id = 3, + ALotOfText = "a lot of text two..." + }; + // This should insert a new entity. + s.Merge(book); + tx.Commit(); + } + + Book bookz = null; + using (ISession s = OpenSession()) + { + bookz = s.Get(3); + Assert.That(bookz, Is.Not.Null); + Assert.That(bookz.Name, Is.EqualTo("some name two")); + Assert.That(bookz.ALotOfText, Is.EqualTo("a lot of text two...")); + + } + using (ISession s = OpenSession()) + { + bookz.Words = new List(); + var word = new Word { Id = 2, Parent = bookz }; + word.Content = new byte[1] { 0 }; + + bookz.Words.Add(word); + s.Merge(bookz); + } + + using (ISession s = OpenSession()) + { + bookz = s.Get(3); + Assert.That(bookz.Words.Any(), Is.True); + Assert.That(bookz.Words.First().Content, Is.EqualTo(new byte[1] { 0 })); + } + } } } diff --git a/src/NHibernate.Test/LazyProperty/Mappings.hbm.xml b/src/NHibernate.Test/LazyProperty/Mappings.hbm.xml index 970fcaaedc0..3cd3a50c268 100644 --- a/src/NHibernate.Test/LazyProperty/Mappings.hbm.xml +++ b/src/NHibernate.Test/LazyProperty/Mappings.hbm.xml @@ -12,6 +12,20 @@ + + + + + + + + + + + + + + diff --git a/src/NHibernate.Test/LazyProperty/Word.cs b/src/NHibernate.Test/LazyProperty/Word.cs new file mode 100644 index 00000000000..125e8038023 --- /dev/null +++ b/src/NHibernate.Test/LazyProperty/Word.cs @@ -0,0 +1,9 @@ +namespace NHibernate.Test.LazyProperty +{ + public class Word + { + public virtual int Id { get; set; } + public virtual byte[] Content { get; set; } + public virtual Book Parent { get; set; } + } +} From 1f565524a4c0067a4926c1680a066da87356f847 Mon Sep 17 00:00:00 2001 From: offan Date: Thu, 24 Jan 2019 20:54:09 +0300 Subject: [PATCH 2/5] fix test --- src/NHibernate.Test/LazyProperty/LazyPropertyFixture.cs | 2 ++ src/NHibernate.Test/LazyProperty/Mappings.hbm.xml | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/NHibernate.Test/LazyProperty/LazyPropertyFixture.cs b/src/NHibernate.Test/LazyProperty/LazyPropertyFixture.cs index 198a2dbeb46..322561fa55c 100644 --- a/src/NHibernate.Test/LazyProperty/LazyPropertyFixture.cs +++ b/src/NHibernate.Test/LazyProperty/LazyPropertyFixture.cs @@ -367,6 +367,7 @@ public void CanMergeTransientWithLazyPropertyInCollenction() } using (ISession s = OpenSession()) + using (var tx = s.BeginTransaction()) { bookz.Words = new List(); var word = new Word { Id = 2, Parent = bookz }; @@ -374,6 +375,7 @@ public void CanMergeTransientWithLazyPropertyInCollenction() bookz.Words.Add(word); s.Merge(bookz); + tx.Commit(); } using (ISession s = OpenSession()) diff --git a/src/NHibernate.Test/LazyProperty/Mappings.hbm.xml b/src/NHibernate.Test/LazyProperty/Mappings.hbm.xml index 3cd3a50c268..432eb11a9e7 100644 --- a/src/NHibernate.Test/LazyProperty/Mappings.hbm.xml +++ b/src/NHibernate.Test/LazyProperty/Mappings.hbm.xml @@ -18,7 +18,7 @@ - + From d9d67371419f14352760f1943e59a081c57dd0c7 Mon Sep 17 00:00:00 2001 From: offan Date: Thu, 24 Jan 2019 21:07:02 +0300 Subject: [PATCH 3/5] fix test1 --- src/NHibernate.Test/LazyProperty/Mappings.hbm.xml | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/NHibernate.Test/LazyProperty/Mappings.hbm.xml b/src/NHibernate.Test/LazyProperty/Mappings.hbm.xml index 432eb11a9e7..1dba1f0c083 100644 --- a/src/NHibernate.Test/LazyProperty/Mappings.hbm.xml +++ b/src/NHibernate.Test/LazyProperty/Mappings.hbm.xml @@ -12,7 +12,7 @@ - + @@ -22,9 +22,7 @@ - - - + From c5cb39cf8d252a0634111879aeff2a8eaf4007c4 Mon Sep 17 00:00:00 2001 From: offan Date: Thu, 24 Jan 2019 21:09:54 +0300 Subject: [PATCH 4/5] fix test2 --- src/NHibernate.Test/LazyProperty/Mappings.hbm.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/NHibernate.Test/LazyProperty/Mappings.hbm.xml b/src/NHibernate.Test/LazyProperty/Mappings.hbm.xml index 1dba1f0c083..d90f7b7181a 100644 --- a/src/NHibernate.Test/LazyProperty/Mappings.hbm.xml +++ b/src/NHibernate.Test/LazyProperty/Mappings.hbm.xml @@ -12,7 +12,7 @@ - + From 60bb573aa77f567c51b520617b7c4a7cb3097e54 Mon Sep 17 00:00:00 2001 From: maca88 Date: Thu, 24 Jan 2019 19:01:28 +0100 Subject: [PATCH 5/5] fix broken test --- .../Async/LazyProperty/LazyPropertyFixture.cs | 53 +++++++++++++++++++ .../LazyProperty/LazyPropertyFixture.cs | 44 ++++++++------- .../LazyProperty/Mappings.hbm.xml | 4 +- src/NHibernate/Async/Type/TypeHelper.cs | 21 +++++++- src/NHibernate/Type/TypeHelper.cs | 21 +++++++- 5 files changed, 120 insertions(+), 23 deletions(-) diff --git a/src/NHibernate.Test/Async/LazyProperty/LazyPropertyFixture.cs b/src/NHibernate.Test/Async/LazyProperty/LazyPropertyFixture.cs index f4807ca8e85..cb8dc0298de 100644 --- a/src/NHibernate.Test/Async/LazyProperty/LazyPropertyFixture.cs +++ b/src/NHibernate.Test/Async/LazyProperty/LazyPropertyFixture.cs @@ -9,6 +9,7 @@ using System.Collections; +using System.Collections.Generic; using System.Linq; using NHibernate.Cfg; using NHibernate.Intercept; @@ -81,6 +82,7 @@ protected override void OnTearDown() using (var s = OpenSession()) using (var tx = s.BeginTransaction()) { + s.CreateQuery("delete from Word").ExecuteUpdate(); s.CreateQuery("delete from Book").ExecuteUpdate(); tx.Commit(); } @@ -345,5 +347,56 @@ public async Task CacheShouldNotContainLazyPropertiesAsync() Assert.That(NHibernateUtil.IsPropertyInitialized(book, "ALotOfText"), Is.False); Assert.That(NHibernateUtil.IsPropertyInitialized(book, "Image"), Is.False); } + + [Test] + public async Task CanMergeTransientWithLazyPropertyInCollectionAsync() + { + Book book; + + using (var s = OpenSession()) + using (var tx = s.BeginTransaction()) + { + book = new Book + { + Name = "some name two", + Id = 3, + ALotOfText = "a lot of text two..." + }; + // This should insert a new entity. + await (s.MergeAsync(book)); + await (tx.CommitAsync()); + } + + using (var s = OpenSession()) + { + book = await (s.GetAsync(3)); + 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...")); + + } + using (var s = OpenSession()) + using (var tx = s.BeginTransaction()) + { + book.Words = new List(); + var word = new Word + { + Id = 2, + Parent = book, + Content = new byte[1] {0} + }; + + book.Words.Add(word); + await (s.MergeAsync(book)); + await (tx.CommitAsync()); + } + + using (var s = OpenSession()) + { + book = await (s.GetAsync(3)); + Assert.That(book.Words.Any(), Is.True); + Assert.That(book.Words.First().Content, Is.EqualTo(new byte[1] { 0 })); + } + } } } diff --git a/src/NHibernate.Test/LazyProperty/LazyPropertyFixture.cs b/src/NHibernate.Test/LazyProperty/LazyPropertyFixture.cs index 322561fa55c..af65b929e69 100644 --- a/src/NHibernate.Test/LazyProperty/LazyPropertyFixture.cs +++ b/src/NHibernate.Test/LazyProperty/LazyPropertyFixture.cs @@ -69,6 +69,7 @@ protected override void OnTearDown() using (var s = OpenSession()) using (var tx = s.BeginTransaction()) { + s.CreateQuery("delete from Word").ExecuteUpdate(); s.CreateQuery("delete from Book").ExecuteUpdate(); tx.Commit(); } @@ -341,12 +342,14 @@ public void CacheShouldNotContainLazyProperties() } [Test] - public void CanMergeTransientWithLazyPropertyInCollenction() + public void CanMergeTransientWithLazyPropertyInCollection() { - using (ISession s = OpenSession()) + Book book; + + using (var s = OpenSession()) using (var tx = s.BeginTransaction()) { - var book = new Book + book = new Book { Name = "some name two", Id = 3, @@ -357,32 +360,35 @@ public void CanMergeTransientWithLazyPropertyInCollenction() tx.Commit(); } - Book bookz = null; - using (ISession s = OpenSession()) + using (var s = OpenSession()) { - bookz = s.Get(3); - Assert.That(bookz, Is.Not.Null); - Assert.That(bookz.Name, Is.EqualTo("some name two")); - Assert.That(bookz.ALotOfText, Is.EqualTo("a lot of text two...")); + book = s.Get(3); + 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...")); } - using (ISession s = OpenSession()) + using (var s = OpenSession()) using (var tx = s.BeginTransaction()) { - bookz.Words = new List(); - var word = new Word { Id = 2, Parent = bookz }; - word.Content = new byte[1] { 0 }; + book.Words = new List(); + var word = new Word + { + Id = 2, + Parent = book, + Content = new byte[1] {0} + }; - bookz.Words.Add(word); - s.Merge(bookz); + book.Words.Add(word); + s.Merge(book); tx.Commit(); } - using (ISession s = OpenSession()) + using (var s = OpenSession()) { - bookz = s.Get(3); - Assert.That(bookz.Words.Any(), Is.True); - Assert.That(bookz.Words.First().Content, Is.EqualTo(new byte[1] { 0 })); + book = s.Get(3); + Assert.That(book.Words.Any(), Is.True); + Assert.That(book.Words.First().Content, Is.EqualTo(new byte[1] { 0 })); } } } diff --git a/src/NHibernate.Test/LazyProperty/Mappings.hbm.xml b/src/NHibernate.Test/LazyProperty/Mappings.hbm.xml index d90f7b7181a..91189c36e30 100644 --- a/src/NHibernate.Test/LazyProperty/Mappings.hbm.xml +++ b/src/NHibernate.Test/LazyProperty/Mappings.hbm.xml @@ -13,7 +13,7 @@ - + @@ -23,7 +23,7 @@ - + diff --git a/src/NHibernate/Async/Type/TypeHelper.cs b/src/NHibernate/Async/Type/TypeHelper.cs index 751418d51d4..4fc408ea24c 100644 --- a/src/NHibernate/Async/Type/TypeHelper.cs +++ b/src/NHibernate/Async/Type/TypeHelper.cs @@ -169,6 +169,25 @@ public static async Task ReplaceAsync(object[] original, object[] targ { copied[i] = target[i]; } + else if (target[i] == LazyPropertyInitializer.UnfetchedProperty) + { + // Should be no need to check for target[i] == PropertyAccessStrategyBackRefImpl.UNKNOWN + // because PropertyAccessStrategyBackRefImpl.get( object ) returns + // PropertyAccessStrategyBackRefImpl.UNKNOWN, so target[i] == original[i]. + // + // We know from above that original[i] != LazyPropertyInitializer.UNFETCHED_PROPERTY && + // original[i] != PropertyAccessStrategyBackRefImpl.UNKNOWN; + // This is a case where the entity being merged has a lazy property + // that has been initialized. Copy the initialized value from original. + if (types[i].IsMutable) + { + copied[i] = types[i].DeepCopy(original[i], session.Factory); + } + else + { + copied[i] = original[i]; + } + } else copied[i] = await (types[i].ReplaceAsync(original[i], target[i], session, owner, copyCache, foreignKeyDirection, cancellationToken)).ConfigureAwait(false); } @@ -343,4 +362,4 @@ public static async Task FindModifiedAsync(StandardProperty[] properties, } } } -} \ No newline at end of file +} diff --git a/src/NHibernate/Type/TypeHelper.cs b/src/NHibernate/Type/TypeHelper.cs index dfb5c38d2ca..a447ef7f64e 100644 --- a/src/NHibernate/Type/TypeHelper.cs +++ b/src/NHibernate/Type/TypeHelper.cs @@ -175,6 +175,25 @@ public static object[] Replace(object[] original, object[] target, IType[] types { copied[i] = target[i]; } + else if (target[i] == LazyPropertyInitializer.UnfetchedProperty) + { + // Should be no need to check for target[i] == PropertyAccessStrategyBackRefImpl.UNKNOWN + // because PropertyAccessStrategyBackRefImpl.get( object ) returns + // PropertyAccessStrategyBackRefImpl.UNKNOWN, so target[i] == original[i]. + // + // We know from above that original[i] != LazyPropertyInitializer.UNFETCHED_PROPERTY && + // original[i] != PropertyAccessStrategyBackRefImpl.UNKNOWN; + // This is a case where the entity being merged has a lazy property + // that has been initialized. Copy the initialized value from original. + if (types[i].IsMutable) + { + copied[i] = types[i].DeepCopy(original[i], session.Factory); + } + else + { + copied[i] = original[i]; + } + } else copied[i] = types[i].Replace(original[i], target[i], session, owner, copyCache, foreignKeyDirection); } @@ -342,4 +361,4 @@ public static int[] FindModified(StandardProperty[] properties, } } } -} \ No newline at end of file +}