Skip to content

Commit 6dba65d

Browse files
authored
Allow using ForeignGenerator with StatelessSession (#2757)
Fixes #1244
1 parent 89a79d2 commit 6dba65d

File tree

4 files changed

+125
-46
lines changed

4 files changed

+125
-46
lines changed

src/NHibernate.Test/Async/OneToOneType/Fixture.cs

Lines changed: 38 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ public class FixtureAsync : BugTestCase
1919
{
2020
protected override void OnTearDown()
2121
{
22-
using (var s = Sfi.OpenSession())
22+
using (var s = OpenSession())
2323
using (var tx = s.BeginTransaction())
2424
{
2525
s.CreateQuery("delete from Details").ExecuteUpdate();
@@ -34,10 +34,10 @@ public async Task OneToOnePersistedOnOwnerUpdateAsync()
3434
{
3535
object ownerId;
3636

37-
using (var s = Sfi.OpenSession())
37+
using (var s = OpenSession())
3838
using (var tx = s.BeginTransaction())
3939
{
40-
var owner = new Owner()
40+
var owner = new Owner
4141
{
4242
Name = "Owner",
4343
};
@@ -52,7 +52,7 @@ public async Task OneToOnePersistedOnOwnerUpdateAsync()
5252
{
5353
Owner owner = await (s.LoadAsync<Owner>(ownerId));
5454

55-
owner.Details = new Details()
55+
owner.Details = new Details
5656
{
5757
Data = "Owner Details"
5858
};
@@ -74,10 +74,10 @@ public async Task OneToOnePersistedOnOwnerUpdateForSessionUpdateAsync()
7474
{
7575
Owner owner;
7676

77-
using (var s = Sfi.OpenSession())
77+
using (var s = OpenSession())
7878
using (var tx = s.BeginTransaction())
7979
{
80-
owner = new Owner()
80+
owner = new Owner
8181
{
8282
Name = "Owner",
8383
};
@@ -95,7 +95,7 @@ public async Task OneToOnePersistedOnOwnerUpdateForSessionUpdateAsync()
9595
using (var tx = s.BeginTransaction())
9696
{
9797
await (s.SaveOrUpdateAsync(owner));
98-
owner.Details = new Details()
98+
owner.Details = new Details
9999
{
100100
Data = "Owner Details"
101101
};
@@ -110,5 +110,36 @@ public async Task OneToOnePersistedOnOwnerUpdateForSessionUpdateAsync()
110110
Assert.IsNotNull(owner.Details);
111111
}
112112
}
113+
114+
[Test]
115+
public async Task CanInsertByStatelessSessionAsync()
116+
{
117+
object id;
118+
119+
using (var s = Sfi.OpenStatelessSession())
120+
using (var tx = s.BeginTransaction())
121+
{
122+
var details = new Details
123+
{
124+
Owner = new Owner
125+
{
126+
Name = "Owner"
127+
},
128+
Data = "Owner Details"
129+
};
130+
131+
id = await (s.InsertAsync(details));
132+
133+
await (tx.CommitAsync());
134+
}
135+
136+
using (var s = OpenSession())
137+
using (s.BeginTransaction())
138+
{
139+
var owner = await (s.GetAsync<Owner>(id));
140+
141+
Assert.That(owner.Details, Is.Not.Null);
142+
}
143+
}
113144
}
114145
}

src/NHibernate.Test/OneToOneType/Fixture.cs

Lines changed: 38 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ public class Fixture : BugTestCase
88
{
99
protected override void OnTearDown()
1010
{
11-
using (var s = Sfi.OpenSession())
11+
using (var s = OpenSession())
1212
using (var tx = s.BeginTransaction())
1313
{
1414
s.CreateQuery("delete from Details").ExecuteUpdate();
@@ -23,10 +23,10 @@ public void OneToOnePersistedOnOwnerUpdate()
2323
{
2424
object ownerId;
2525

26-
using (var s = Sfi.OpenSession())
26+
using (var s = OpenSession())
2727
using (var tx = s.BeginTransaction())
2828
{
29-
var owner = new Owner()
29+
var owner = new Owner
3030
{
3131
Name = "Owner",
3232
};
@@ -41,7 +41,7 @@ public void OneToOnePersistedOnOwnerUpdate()
4141
{
4242
Owner owner = s.Load<Owner>(ownerId);
4343

44-
owner.Details = new Details()
44+
owner.Details = new Details
4545
{
4646
Data = "Owner Details"
4747
};
@@ -63,10 +63,10 @@ public void OneToOnePersistedOnOwnerUpdateForSessionUpdate()
6363
{
6464
Owner owner;
6565

66-
using (var s = Sfi.OpenSession())
66+
using (var s = OpenSession())
6767
using (var tx = s.BeginTransaction())
6868
{
69-
owner = new Owner()
69+
owner = new Owner
7070
{
7171
Name = "Owner",
7272
};
@@ -84,7 +84,7 @@ public void OneToOnePersistedOnOwnerUpdateForSessionUpdate()
8484
using (var tx = s.BeginTransaction())
8585
{
8686
s.SaveOrUpdate(owner);
87-
owner.Details = new Details()
87+
owner.Details = new Details
8888
{
8989
Data = "Owner Details"
9090
};
@@ -99,5 +99,36 @@ public void OneToOnePersistedOnOwnerUpdateForSessionUpdate()
9999
Assert.IsNotNull(owner.Details);
100100
}
101101
}
102+
103+
[Test]
104+
public void CanInsertByStatelessSession()
105+
{
106+
object id;
107+
108+
using (var s = Sfi.OpenStatelessSession())
109+
using (var tx = s.BeginTransaction())
110+
{
111+
var details = new Details
112+
{
113+
Owner = new Owner
114+
{
115+
Name = "Owner"
116+
},
117+
Data = "Owner Details"
118+
};
119+
120+
id = s.Insert(details);
121+
122+
tx.Commit();
123+
}
124+
125+
using (var s = OpenSession())
126+
using (s.BeginTransaction())
127+
{
128+
var owner = s.Get<Owner>(id);
129+
130+
Assert.That(owner.Details, Is.Not.Null);
131+
}
132+
}
102133
}
103134
}

src/NHibernate/Async/Id/ForeignGenerator.cs

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
using System.Collections;
1212
using System.Collections.Generic;
1313
using NHibernate.Engine;
14+
using NHibernate.Persister.Entity;
1415
using NHibernate.Type;
1516

1617
namespace NHibernate.Id
@@ -36,8 +37,6 @@ public partial class ForeignGenerator : IIdentifierGenerator, IConfigurable
3637
public async Task<object> GenerateAsync(ISessionImplementor sessionImplementor, object obj, CancellationToken cancellationToken)
3738
{
3839
cancellationToken.ThrowIfCancellationRequested();
39-
ISession session = (ISession) sessionImplementor;
40-
4140
var persister = sessionImplementor.Factory.GetEntityPersister(entityName);
4241
object associatedObject = persister.GetPropertyValue(obj, propertyName);
4342

@@ -46,17 +45,7 @@ public async Task<object> GenerateAsync(ISessionImplementor sessionImplementor,
4645
throw new IdentifierGenerationException("attempted to assign id from null one-to-one property: " + propertyName);
4746
}
4847

49-
EntityType foreignValueSourceType;
50-
IType propertyType = persister.GetPropertyType(propertyName);
51-
if (propertyType.IsEntityType)
52-
{
53-
foreignValueSourceType = (EntityType) propertyType;
54-
}
55-
else
56-
{
57-
// try identifier mapper
58-
foreignValueSourceType = (EntityType) persister.GetPropertyType("_identifierMapper." + propertyName);
59-
}
48+
var foreignValueSourceType = GetForeignValueSourceType(persister);
6049

6150
object id;
6251
try
@@ -68,10 +57,21 @@ public async Task<object> GenerateAsync(ISessionImplementor sessionImplementor,
6857
}
6958
catch (TransientObjectException)
7059
{
71-
id = await (session.SaveAsync(foreignValueSourceType.GetAssociatedEntityName(), associatedObject, cancellationToken)).ConfigureAwait(false);
60+
if (sessionImplementor is ISession session)
61+
{
62+
id = await (session.SaveAsync(foreignValueSourceType.GetAssociatedEntityName(), associatedObject, cancellationToken)).ConfigureAwait(false);
63+
}
64+
else if (sessionImplementor is IStatelessSession statelessSession)
65+
{
66+
id = await (statelessSession.InsertAsync(foreignValueSourceType.GetAssociatedEntityName(), associatedObject, cancellationToken)).ConfigureAwait(false);
67+
}
68+
else
69+
{
70+
throw new IdentifierGenerationException("sessionImplementor is neither Session nor StatelessSession");
71+
}
7272
}
7373

74-
if (session.Contains(obj))
74+
if (Contains(sessionImplementor, obj))
7575
{
7676
//abort the save (the object is already saved by a circular cascade)
7777
return IdentifierGeneratorFactory.ShortCircuitIndicator;
@@ -82,4 +82,4 @@ public async Task<object> GenerateAsync(ISessionImplementor sessionImplementor,
8282

8383
#endregion
8484
}
85-
}
85+
}

src/NHibernate/Id/ForeignGenerator.cs

Lines changed: 33 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
using System.Collections;
22
using System.Collections.Generic;
33
using NHibernate.Engine;
4+
using NHibernate.Persister.Entity;
45
using NHibernate.Type;
56

67
namespace NHibernate.Id
@@ -39,8 +40,6 @@ public partial class ForeignGenerator : IIdentifierGenerator, IConfigurable
3940
/// </returns>
4041
public object Generate(ISessionImplementor sessionImplementor, object obj)
4142
{
42-
ISession session = (ISession) sessionImplementor;
43-
4443
var persister = sessionImplementor.Factory.GetEntityPersister(entityName);
4544
object associatedObject = persister.GetPropertyValue(obj, propertyName);
4645

@@ -49,17 +48,7 @@ public object Generate(ISessionImplementor sessionImplementor, object obj)
4948
throw new IdentifierGenerationException("attempted to assign id from null one-to-one property: " + propertyName);
5049
}
5150

52-
EntityType foreignValueSourceType;
53-
IType propertyType = persister.GetPropertyType(propertyName);
54-
if (propertyType.IsEntityType)
55-
{
56-
foreignValueSourceType = (EntityType) propertyType;
57-
}
58-
else
59-
{
60-
// try identifier mapper
61-
foreignValueSourceType = (EntityType) persister.GetPropertyType("_identifierMapper." + propertyName);
62-
}
51+
var foreignValueSourceType = GetForeignValueSourceType(persister);
6352

6453
object id;
6554
try
@@ -71,10 +60,21 @@ public object Generate(ISessionImplementor sessionImplementor, object obj)
7160
}
7261
catch (TransientObjectException)
7362
{
74-
id = session.Save(foreignValueSourceType.GetAssociatedEntityName(), associatedObject);
63+
if (sessionImplementor is ISession session)
64+
{
65+
id = session.Save(foreignValueSourceType.GetAssociatedEntityName(), associatedObject);
66+
}
67+
else if (sessionImplementor is IStatelessSession statelessSession)
68+
{
69+
id = statelessSession.Insert(foreignValueSourceType.GetAssociatedEntityName(), associatedObject);
70+
}
71+
else
72+
{
73+
throw new IdentifierGenerationException("sessionImplementor is neither Session nor StatelessSession");
74+
}
7575
}
7676

77-
if (session.Contains(obj))
77+
if (Contains(sessionImplementor, obj))
7878
{
7979
//abort the save (the object is already saved by a circular cascade)
8080
return IdentifierGeneratorFactory.ShortCircuitIndicator;
@@ -83,6 +83,23 @@ public object Generate(ISessionImplementor sessionImplementor, object obj)
8383
return id;
8484
}
8585

86+
private EntityType GetForeignValueSourceType(IEntityPersister persister)
87+
{
88+
var propertyType = persister.GetPropertyType(propertyName);
89+
if (propertyType.IsEntityType)
90+
{
91+
return (EntityType) propertyType;
92+
}
93+
94+
// try identifier mapper
95+
return (EntityType) persister.GetPropertyType("_identifierMapper." + propertyName);
96+
}
97+
98+
private static bool Contains(ISessionImplementor sessionImplementor, object obj)
99+
{
100+
return sessionImplementor is ISession session && session.Contains(obj);
101+
}
102+
86103
#endregion
87104

88105
#region IConfigurable Members
@@ -109,4 +126,4 @@ public void Configure(IType type, IDictionary<string, string> parms, Dialect.Dia
109126

110127
#endregion
111128
}
112-
}
129+
}

0 commit comments

Comments
 (0)