Skip to content

Commit a7a0ebb

Browse files
authored
Fix Refresh and Load event listeners for entity proxy (#2949)
Fixes #2727 Fixes #2928
1 parent 92075ee commit a7a0ebb

File tree

7 files changed

+200
-6
lines changed

7 files changed

+200
-6
lines changed
Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
//------------------------------------------------------------------------------
2+
// <auto-generated>
3+
// This code was generated by AsyncGenerator.
4+
//
5+
// Changes to this file may cause incorrect behavior and will be lost if
6+
// the code is regenerated.
7+
// </auto-generated>
8+
//------------------------------------------------------------------------------
9+
10+
11+
using System;
12+
using NHibernate.Cfg.MappingSchema;
13+
using NHibernate.Mapping.ByCode;
14+
using NUnit.Framework;
15+
16+
namespace NHibernate.Test.NHSpecificTest.GH2727
17+
{
18+
using System.Threading.Tasks;
19+
/// <summary>
20+
/// Fixture using 'by code' mappings
21+
/// </summary>
22+
[TestFixture]
23+
public class LazyPropByCodeFixtureAsync : TestCaseMappingByCode
24+
{
25+
private Guid id1;
26+
private Guid id2;
27+
28+
protected override HbmMapping GetMappings()
29+
{
30+
var mapper = new ModelMapper();
31+
mapper.Class<Entity>(
32+
rc =>
33+
{
34+
rc.Id(x => x.Id, m => m.Generator(Generators.GuidComb));
35+
rc.Property(x => x.Name);
36+
rc.Property(x => x.LazyProp, m => m.Lazy(true));
37+
});
38+
39+
return mapper.CompileMappingForAllExplicitlyAddedEntities();
40+
}
41+
42+
protected override void OnSetUp()
43+
{
44+
using (var session = OpenSession())
45+
using (var transaction = session.BeginTransaction())
46+
{
47+
var e1 = new Entity { Name = "Bob" };
48+
session.Save(e1);
49+
50+
var e2 = new Entity { Name = "Sally" };
51+
session.Save(e2);
52+
53+
transaction.Commit();
54+
id1 = e1.Id;
55+
id2 = e2.Id;
56+
}
57+
}
58+
59+
protected override void OnTearDown()
60+
{
61+
using (var session = OpenSession())
62+
using (var transaction = session.BeginTransaction())
63+
{
64+
// The HQL delete does all the job inside the database without loading the entities, but it does
65+
// not handle delete order for avoiding violating constraints if any. Use
66+
// session.Delete("from System.Object");
67+
// instead if in need of having NHbernate ordering the deletes, but this will cause
68+
// loading the entities in the session.
69+
session.CreateQuery("delete from System.Object").ExecuteUpdate();
70+
71+
transaction.Commit();
72+
}
73+
}
74+
75+
[Test]
76+
public async Task CanLoadUsingInstanceAsync()
77+
{
78+
using (var s = OpenSession())
79+
{
80+
var e1 = await (s.LoadAsync<Entity>(id1));
81+
await (s.LoadAsync(e1, id2));
82+
}
83+
}
84+
85+
[Test(Description = "GH-2928")]
86+
public async Task CanSessionRefreshEntityWithLazyPropertiesAsync()
87+
{
88+
using (var s = OpenSession())
89+
{
90+
var e1 = await (s.GetAsync<Entity>(id1));
91+
await (s.RefreshAsync(e1));
92+
s.Clear();
93+
await (s.RefreshAsync(e1));
94+
}
95+
}
96+
}
97+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
using System;
2+
3+
namespace NHibernate.Test.NHSpecificTest.GH2727
4+
{
5+
public class Entity
6+
{
7+
public virtual Guid Id { get; set; }
8+
public virtual string Name { get; set; }
9+
public virtual string LazyProp { get; set; }
10+
}
11+
}
Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
using System;
2+
using NHibernate.Cfg.MappingSchema;
3+
using NHibernate.Mapping.ByCode;
4+
using NUnit.Framework;
5+
6+
namespace NHibernate.Test.NHSpecificTest.GH2727
7+
{
8+
/// <summary>
9+
/// Fixture using 'by code' mappings
10+
/// </summary>
11+
[TestFixture]
12+
public class LazyPropByCodeFixture : TestCaseMappingByCode
13+
{
14+
private Guid id1;
15+
private Guid id2;
16+
17+
protected override HbmMapping GetMappings()
18+
{
19+
var mapper = new ModelMapper();
20+
mapper.Class<Entity>(
21+
rc =>
22+
{
23+
rc.Id(x => x.Id, m => m.Generator(Generators.GuidComb));
24+
rc.Property(x => x.Name);
25+
rc.Property(x => x.LazyProp, m => m.Lazy(true));
26+
});
27+
28+
return mapper.CompileMappingForAllExplicitlyAddedEntities();
29+
}
30+
31+
protected override void OnSetUp()
32+
{
33+
using (var session = OpenSession())
34+
using (var transaction = session.BeginTransaction())
35+
{
36+
var e1 = new Entity { Name = "Bob" };
37+
session.Save(e1);
38+
39+
var e2 = new Entity { Name = "Sally" };
40+
session.Save(e2);
41+
42+
transaction.Commit();
43+
id1 = e1.Id;
44+
id2 = e2.Id;
45+
}
46+
}
47+
48+
protected override void OnTearDown()
49+
{
50+
using (var session = OpenSession())
51+
using (var transaction = session.BeginTransaction())
52+
{
53+
// The HQL delete does all the job inside the database without loading the entities, but it does
54+
// not handle delete order for avoiding violating constraints if any. Use
55+
// session.Delete("from System.Object");
56+
// instead if in need of having NHbernate ordering the deletes, but this will cause
57+
// loading the entities in the session.
58+
session.CreateQuery("delete from System.Object").ExecuteUpdate();
59+
60+
transaction.Commit();
61+
}
62+
}
63+
64+
[Test]
65+
public void CanLoadUsingInstance()
66+
{
67+
using (var s = OpenSession())
68+
{
69+
var e1 = s.Load<Entity>(id1);
70+
s.Load(e1, id2);
71+
}
72+
}
73+
74+
[Test(Description = "GH-2928")]
75+
public void CanSessionRefreshEntityWithLazyProperties()
76+
{
77+
using (var s = OpenSession())
78+
{
79+
var e1 = s.Get<Entity>(id1);
80+
s.Refresh(e1);
81+
s.Clear();
82+
s.Refresh(e1);
83+
}
84+
}
85+
}
86+
}

src/NHibernate/Async/Event/Default/DefaultLoadEventListener.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,8 @@ public virtual async Task OnLoadAsync(LoadEvent @event, LoadType loadType, Cance
3737
IEntityPersister persister;
3838
if (@event.InstanceToLoad != null)
3939
{
40-
persister = source.GetEntityPersister(null, @event.InstanceToLoad); //the load() which takes an entity does not pass an entityName
41-
@event.EntityClassName = @event.InstanceToLoad.GetType().FullName;
40+
@event.EntityClassName = source.BestGuessEntityName(@event.InstanceToLoad); //the load() which takes an entity does not pass an entityName
41+
persister = source.GetEntityPersister(@event.EntityClassName, @event.InstanceToLoad);
4242
}
4343
else
4444
{

src/NHibernate/Async/Event/Default/DefaultRefreshEventListener.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ public virtual async Task OnRefreshAsync(RefreshEvent @event, IDictionary refres
6868

6969
if (e == null)
7070
{
71-
persister = source.GetEntityPersister(null, obj); //refresh() does not pass an entityName
71+
persister = source.GetEntityPersister(source.BestGuessEntityName(obj), obj); //refresh() does not pass an entityName
7272
id = persister.GetIdentifier(obj);
7373
if (log.IsDebugEnabled())
7474
{

src/NHibernate/Event/Default/DefaultLoadEventListener.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,8 @@ public virtual void OnLoad(LoadEvent @event, LoadType loadType)
3333
IEntityPersister persister;
3434
if (@event.InstanceToLoad != null)
3535
{
36-
persister = source.GetEntityPersister(null, @event.InstanceToLoad); //the load() which takes an entity does not pass an entityName
37-
@event.EntityClassName = @event.InstanceToLoad.GetType().FullName;
36+
@event.EntityClassName = source.BestGuessEntityName(@event.InstanceToLoad); //the load() which takes an entity does not pass an entityName
37+
persister = source.GetEntityPersister(@event.EntityClassName, @event.InstanceToLoad);
3838
}
3939
else
4040
{

src/NHibernate/Event/Default/DefaultRefreshEventListener.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ public virtual void OnRefresh(RefreshEvent @event, IDictionary refreshedAlready)
5050

5151
if (e == null)
5252
{
53-
persister = source.GetEntityPersister(null, obj); //refresh() does not pass an entityName
53+
persister = source.GetEntityPersister(source.BestGuessEntityName(obj), obj); //refresh() does not pass an entityName
5454
id = persister.GetIdentifier(obj);
5555
if (log.IsDebugEnabled())
5656
{

0 commit comments

Comments
 (0)