Skip to content

Commit 1581887

Browse files
authored
Fix ExtractInterceptor for subclasses (#2509)
Fixes #2508
1 parent ea56cbc commit 1581887

File tree

9 files changed

+275
-2
lines changed

9 files changed

+275
-2
lines changed
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
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 System.Linq;
13+
using System.Threading;
14+
using System.Threading.Tasks;
15+
using NHibernate.Cfg;
16+
using NHibernate.Event;
17+
using NHibernate.Persister.Entity;
18+
19+
namespace NHibernate.Test.NHSpecificTest.GH2508
20+
{
21+
public partial class AuditEventListener : IPreCollectionUpdateEventListener
22+
{
23+
public Task OnPreUpdateCollectionAsync(PreCollectionUpdateEvent @event, CancellationToken cancellationToken)
24+
{
25+
try
26+
{
27+
var ownerEntity = @event.AffectedOwnerOrNull;
28+
var collectionEntry = @event.Session.PersistenceContext.GetCollectionEntry(@event.Collection);
29+
if (!collectionEntry.LoadedPersister.IsInverse)
30+
return Task.CompletedTask;
31+
32+
var abstractCollectionPersister = collectionEntry.LoadedPersister as Persister.Collection.AbstractCollectionPersister;
33+
if (abstractCollectionPersister == null)
34+
return Task.CompletedTask;
35+
36+
var ownerEntityPersister = abstractCollectionPersister.OwnerEntityPersister;
37+
ownerEntityPersister.GetPropertyValues(ownerEntity);
38+
return Task.CompletedTask;
39+
}
40+
catch (Exception ex)
41+
{
42+
return Task.FromException<object>(ex);
43+
}
44+
}
45+
}
46+
}
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
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.Linq;
12+
using NHibernate.Cfg;
13+
using NUnit.Framework;
14+
using NHibernate.Linq;
15+
16+
namespace NHibernate.Test.NHSpecificTest.GH2508
17+
{
18+
using System.Threading.Tasks;
19+
[TestFixture]
20+
public class FixtureAsync : BugTestCase
21+
{
22+
protected override void Configure(Configuration configuration)
23+
{
24+
var listeners = configuration.EventListeners;
25+
listeners.PreCollectionUpdateEventListeners =
26+
new[] {new AuditEventListener()}
27+
.Concat(listeners.PreCollectionUpdateEventListeners)
28+
.ToArray();
29+
}
30+
31+
protected override void OnSetUp()
32+
{
33+
using (var session = OpenSession())
34+
using (var transaction = session.BeginTransaction())
35+
{
36+
var e1 = new LoggerCase {Name = "Bob"};
37+
session.Save(e1);
38+
39+
var e2 = new LoggerCase {Name = "Sally"};
40+
session.Save(e2);
41+
42+
transaction.Commit();
43+
}
44+
}
45+
46+
protected override void OnTearDown()
47+
{
48+
using (var session = OpenSession())
49+
using (var transaction = session.BeginTransaction())
50+
{
51+
session.Delete("from System.Object");
52+
transaction.Commit();
53+
}
54+
}
55+
56+
[Test]
57+
public async Task TestPreCollectionUpdateEventAsync()
58+
{
59+
using (var session = OpenSession())
60+
using (var transaction = session.BeginTransaction())
61+
{
62+
var result = await ((from e in session.Query<LoggerCase>()
63+
where e.Name == "Bob"
64+
select e).FirstAsync());
65+
66+
result.Children.Add(new Child { Logger = result, Name = "child" });
67+
await (session.SaveOrUpdateAsync(result));
68+
await (transaction.CommitAsync());
69+
}
70+
}
71+
}
72+
}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
using System;
2+
using System.Linq;
3+
using System.Threading;
4+
using System.Threading.Tasks;
5+
using NHibernate.Cfg;
6+
using NHibernate.Event;
7+
using NHibernate.Persister.Entity;
8+
9+
namespace NHibernate.Test.NHSpecificTest.GH2508
10+
{
11+
public partial class AuditEventListener : IPreCollectionUpdateEventListener
12+
{
13+
public void OnPreUpdateCollection(PreCollectionUpdateEvent @event)
14+
{
15+
var ownerEntity = @event.AffectedOwnerOrNull;
16+
var collectionEntry = @event.Session.PersistenceContext.GetCollectionEntry(@event.Collection);
17+
if (!collectionEntry.LoadedPersister.IsInverse)
18+
return;
19+
20+
var abstractCollectionPersister = collectionEntry.LoadedPersister as Persister.Collection.AbstractCollectionPersister;
21+
if (abstractCollectionPersister == null)
22+
return;
23+
24+
var ownerEntityPersister = abstractCollectionPersister.OwnerEntityPersister;
25+
ownerEntityPersister.GetPropertyValues(ownerEntity);
26+
}
27+
}
28+
}
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.GH2508
4+
{
5+
public class Child
6+
{
7+
public virtual Guid Id { get; set; }
8+
public virtual string Name { get; set; }
9+
public virtual LoggerBase Logger { get; set; }
10+
}
11+
}
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
using System.Linq;
2+
using NHibernate.Cfg;
3+
using NUnit.Framework;
4+
5+
namespace NHibernate.Test.NHSpecificTest.GH2508
6+
{
7+
[TestFixture]
8+
public class Fixture : BugTestCase
9+
{
10+
protected override void Configure(Configuration configuration)
11+
{
12+
var listeners = configuration.EventListeners;
13+
listeners.PreCollectionUpdateEventListeners =
14+
new[] {new AuditEventListener()}
15+
.Concat(listeners.PreCollectionUpdateEventListeners)
16+
.ToArray();
17+
}
18+
19+
protected override void OnSetUp()
20+
{
21+
using (var session = OpenSession())
22+
using (var transaction = session.BeginTransaction())
23+
{
24+
var e1 = new LoggerCase {Name = "Bob"};
25+
session.Save(e1);
26+
27+
var e2 = new LoggerCase {Name = "Sally"};
28+
session.Save(e2);
29+
30+
transaction.Commit();
31+
}
32+
}
33+
34+
protected override void OnTearDown()
35+
{
36+
using (var session = OpenSession())
37+
using (var transaction = session.BeginTransaction())
38+
{
39+
session.Delete("from System.Object");
40+
transaction.Commit();
41+
}
42+
}
43+
44+
[Test]
45+
public void TestPreCollectionUpdateEvent()
46+
{
47+
using (var session = OpenSession())
48+
using (var transaction = session.BeginTransaction())
49+
{
50+
var result = (from e in session.Query<LoggerCase>()
51+
where e.Name == "Bob"
52+
select e).First();
53+
54+
result.Children.Add(new Child { Logger = result, Name = "child" });
55+
session.SaveOrUpdate(result);
56+
transaction.Commit();
57+
}
58+
}
59+
}
60+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
using System;
2+
using System.Collections.Generic;
3+
4+
namespace NHibernate.Test.NHSpecificTest.GH2508
5+
{
6+
public abstract class LoggerBase
7+
{
8+
public LoggerBase()
9+
{
10+
Children = new List<Child>();
11+
}
12+
13+
public virtual string Solution { get; set; }
14+
15+
public virtual Guid Id { get; set; }
16+
17+
public virtual string Name { get; set; }
18+
19+
public virtual IList<Child> Children { get; set; }
20+
}
21+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
namespace NHibernate.Test.NHSpecificTest.GH2508
2+
{
3+
public class LoggerCase : LoggerBase
4+
{
5+
public virtual string Description { get; set; }
6+
}
7+
}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
<?xml version="1.0" encoding="utf-8" ?>
2+
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" assembly="NHibernate.Test"
3+
namespace="NHibernate.Test.NHSpecificTest.GH2508">
4+
5+
<class name="LoggerBase" abstract="true" polymorphism="implicit">
6+
<id name="Id" generator="guid.comb"/>
7+
8+
<property name="Name"/>
9+
<property name="Solution" type="StringClob" lazy="true"/>
10+
11+
<bag name="Children" cascade="all-delete-orphan" inverse="true">
12+
<key column="LoggerBaseId"/>
13+
<one-to-many class="Child"/>
14+
</bag>
15+
16+
<joined-subclass name="LoggerCase">
17+
<key column="Id" />
18+
<property name="Description"/>
19+
</joined-subclass>
20+
</class>
21+
22+
<class name="Child">
23+
<id name="Id" generator="guid.comb"/>
24+
25+
<many-to-one name="Logger" class="LoggerBase" column="LoggerBaseId" />
26+
<property name="Name"/>
27+
</class>
28+
</hibernate-mapping>

src/NHibernate/Tuple/Entity/BytecodeEnhancementMetadataPocoImpl.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,7 @@ public IFieldInterceptor InjectInterceptor(object entity, ISessionImplementor se
132132
return null; // Can happen when a saved entity is refreshed within the same session NH2860
133133
}
134134

135-
if (entity.GetType().BaseType != _entityType)
135+
if (!_entityType.IsInstanceOfType(entity))
136136
{
137137
throw new ArgumentException(
138138
$"Passed entity instance [{entity}] is not of expected type [{EntityName}]");
@@ -170,7 +170,7 @@ public IFieldInterceptor ExtractInterceptor(object entity)
170170
return null;
171171
}
172172

173-
if (_entityType != interceptor.MappedClass)
173+
if (!_entityType.IsAssignableFrom(interceptor.MappedClass))
174174
{
175175
throw new ArgumentException(
176176
$"Passed entity instance [{entity}] is not of expected type [{EntityName}]");

0 commit comments

Comments
 (0)