Skip to content

Commit 3897703

Browse files
committed
Merge branch 'desunit-NH-1882' into 3.4.x
2 parents 7afda71 + 724bed6 commit 3897703

File tree

6 files changed

+206
-1
lines changed

6 files changed

+206
-1
lines changed
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
using System;
2+
using Iesi.Collections.Generic;
3+
4+
namespace NHibernate.Test.NHSpecificTest.NH1882
5+
{
6+
public class Author
7+
{
8+
public Author()
9+
{
10+
Books = new HashedSet<Book>();
11+
}
12+
13+
public Author(String name)
14+
{
15+
Books = new HashedSet<Book>();
16+
Name = name;
17+
}
18+
19+
public virtual int Id { get; set; }
20+
21+
public virtual string Name { get; set; }
22+
23+
public virtual Publisher Publisher { get; set; }
24+
25+
public virtual ISet<Book> Books { get; set; }
26+
}
27+
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
using System;
2+
3+
namespace NHibernate.Test.NHSpecificTest.NH1882
4+
{
5+
public class Book
6+
{
7+
public Book()
8+
{
9+
}
10+
11+
public Book(String title, Author author)
12+
{
13+
Title = title;
14+
Author = author;
15+
}
16+
17+
public virtual int Id { get; set; }
18+
19+
public virtual string Title { get; set; }
20+
21+
public virtual Author Author { get; set; }
22+
}
23+
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
using System;
2+
using Iesi.Collections.Generic;
3+
4+
namespace NHibernate.Test.NHSpecificTest.NH1882
5+
{
6+
public class Publisher
7+
{
8+
public Publisher()
9+
{
10+
Authors = new HashedSet<Author>();
11+
}
12+
13+
public Publisher(String name)
14+
{
15+
Authors = new HashedSet<Author>();
16+
Name = name;
17+
}
18+
19+
public virtual int Id { get; set; }
20+
21+
public virtual string Name { get; set; }
22+
23+
public virtual ISet<Author> Authors { get; set; }
24+
}
25+
}
Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
using System;
2+
using NHibernate.Cfg;
3+
using NHibernate.Cfg.MappingSchema;
4+
using NHibernate.Event;
5+
using NHibernate.Mapping.ByCode;
6+
using NUnit.Framework;
7+
8+
namespace NHibernate.Test.NHSpecificTest.NH1882
9+
{
10+
[TestFixture]
11+
public class TestCollectionInitializingDuringFlush : TestCaseMappingByCode
12+
{
13+
private readonly InitializingPreUpdateEventListener listener = new InitializingPreUpdateEventListener();
14+
15+
protected override void Configure(Configuration configuration)
16+
{
17+
configuration.EventListeners.PreUpdateEventListeners = new IPreUpdateEventListener[]
18+
{
19+
listener
20+
};
21+
base.Configure(configuration);
22+
}
23+
24+
protected override HbmMapping GetMappings()
25+
{
26+
var mapper = new ModelMapper();
27+
mapper.Class<Author>(rc =>
28+
{
29+
rc.Id(x => x.Id, m => m.Generator(Generators.Identity));
30+
rc.Property(x => x.Name);
31+
rc.ManyToOne(x => x.Publisher, m => m.Cascade(Mapping.ByCode.Cascade.All));
32+
rc.Set(x => x.Books, m =>
33+
{
34+
m.Cascade(Mapping.ByCode.Cascade.All);
35+
m.Lazy(CollectionLazy.Lazy);
36+
}, r => r.OneToMany());
37+
});
38+
mapper.Class<Book>(rc =>
39+
{
40+
rc.Id(x => x.Id, m => m.Generator(Generators.Identity));
41+
rc.Property(x => x.Title);
42+
rc.ManyToOne(x => x.Author);
43+
});
44+
mapper.Class<Publisher>(rc =>
45+
{
46+
rc.Id(x => x.Id, m => m.Generator(Generators.Identity));
47+
rc.Property(x => x.Name);
48+
rc.Set(x => x.Authors, m => m.Cascade(Mapping.ByCode.Cascade.All), r => r.OneToMany());
49+
});
50+
51+
return mapper.CompileMappingForAllExplicitlyAddedEntities();
52+
}
53+
54+
public class InitializingPreUpdateEventListener : IPreUpdateEventListener
55+
{
56+
public static InitializingPreUpdateEventListener Instance = new InitializingPreUpdateEventListener();
57+
58+
public bool Executed { get; set; }
59+
60+
public bool FoundAny { get; set; }
61+
62+
public bool OnPreUpdate(PreUpdateEvent @event)
63+
{
64+
Executed = true;
65+
Object[] oldValues = @event.OldState;
66+
String[] properties = @event.Persister.PropertyNames;
67+
68+
// Iterate through all fields of the updated object
69+
for (int i = 0; i < properties.Length; i++)
70+
{
71+
if (oldValues != null && oldValues[i] != null)
72+
{
73+
if (! NHibernateUtil.IsInitialized(oldValues[i]))
74+
{
75+
// force any proxies and/or collections to initialize to illustrate HHH-2763
76+
FoundAny = true;
77+
NHibernateUtil.Initialize(oldValues[i]);
78+
}
79+
}
80+
}
81+
return true;
82+
}
83+
}
84+
85+
[Test]
86+
public void TestInitializationDuringFlush()
87+
{
88+
Assert.False(listener.Executed);
89+
Assert.False(listener.FoundAny);
90+
ISession s = OpenSession();
91+
s.BeginTransaction();
92+
var publisher = new Publisher("acme");
93+
var author = new Author("john");
94+
author.Publisher = publisher;
95+
publisher.Authors.Add(author);
96+
author.Books.Add(new Book("Reflections on a Wimpy Kid", author));
97+
s.Save(author);
98+
s.Transaction.Commit();
99+
s.Clear();
100+
101+
s = OpenSession();
102+
s.BeginTransaction();
103+
publisher = s.Get<Publisher>(publisher.Id);
104+
publisher.Name = "random nally";
105+
s.Flush();
106+
s.Transaction.Commit();
107+
s.Clear();
108+
109+
s = OpenSession();
110+
s.BeginTransaction();
111+
s.Delete(author);
112+
s.Transaction.Commit();
113+
s.Clear();
114+
s.Close();
115+
Assert.True(listener.Executed);
116+
Assert.True(listener.FoundAny);
117+
}
118+
}
119+
}

src/NHibernate.Test/NHibernate.Test.csproj

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -671,6 +671,10 @@
671671
<Compile Include="NHSpecificTest\BagWithLazyExtraAndFilter\Fixture.cs" />
672672
<Compile Include="Component\Basic\ComponentWithUniqueConstraintTests.cs" />
673673
<Compile Include="MappingByCode\ExpliticMappingTests\ClassWithoutNamespaceTests.cs" />
674+
<Compile Include="NHSpecificTest\NH1882\Author.cs" />
675+
<Compile Include="NHSpecificTest\NH1882\Book.cs" />
676+
<Compile Include="NHSpecificTest\NH1882\Publisher.cs" />
677+
<Compile Include="NHSpecificTest\NH1882\TestCollectionInitializingDuringFlush.cs" />
674678
<Compile Include="NHSpecificTest\NH3614\Entity.cs" />
675679
<Compile Include="NHSpecificTest\NH3614\Fixture.cs" />
676680
<Compile Include="NHSpecificTest\NH3505\Student.cs" />
@@ -3445,4 +3449,4 @@ if exist hibernate.cfg.xml (del hibernate.cfg.xml)
34453449
if exist "$(ProjectDir)hibernate.cfg.xml" (copy "$(ProjectDir)hibernate.cfg.xml" "hibernate.cfg.xml")
34463450
copy /y "..\..\..\NHibernate.DomainModel\ABC.hbm.xml" "ABC.hbm.xml"</PostBuildEvent>
34473451
</PropertyGroup>
3448-
</Project>
3452+
</Project>

src/NHibernate/Event/Default/AbstractFlushingEventListener.cs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -225,6 +225,7 @@ protected virtual void CascadeOnFlush(IEventSource session, IEntityPersister per
225225
/// <item> <description>Deletes, in the order they were performed</description> </item>
226226
/// </list>
227227
/// </summary>
228+
/// <param name="session">The session being flushed</param>
228229
protected virtual void PerformExecutions(IEventSource session)
229230
{
230231
if (log.IsDebugEnabled)
@@ -235,6 +236,11 @@ protected virtual void PerformExecutions(IEventSource session)
235236
try
236237
{
237238
session.ConnectionManager.FlushBeginning();
239+
// IMPL NOTE : here we alter the flushing flag of the persistence context to allow
240+
// during-flush callbacks more leniency in regards to initializing proxies and
241+
// lazy collections during their processing.
242+
// For more information, see HHH-2763 / NH-1882
243+
session.PersistenceContext.Flushing = true;
238244
// we need to lock the collection caches before
239245
// executing entity inserts/updates in order to
240246
// account for bidi associations
@@ -251,6 +257,7 @@ protected virtual void PerformExecutions(IEventSource session)
251257
}
252258
finally
253259
{
260+
session.PersistenceContext.Flushing = false;
254261
session.ConnectionManager.FlushEnding();
255262
}
256263
}

0 commit comments

Comments
 (0)