Skip to content

Allow using ForeignGenerator with StatelessSession #2757

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
May 15, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 38 additions & 7 deletions src/NHibernate.Test/Async/OneToOneType/Fixture.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ public class FixtureAsync : BugTestCase
{
protected override void OnTearDown()
{
using (var s = Sfi.OpenSession())
using (var s = OpenSession())
using (var tx = s.BeginTransaction())
{
s.CreateQuery("delete from Details").ExecuteUpdate();
Expand All @@ -34,10 +34,10 @@ public async Task OneToOnePersistedOnOwnerUpdateAsync()
{
object ownerId;

using (var s = Sfi.OpenSession())
using (var s = OpenSession())
using (var tx = s.BeginTransaction())
{
var owner = new Owner()
var owner = new Owner
{
Name = "Owner",
};
Expand All @@ -52,7 +52,7 @@ public async Task OneToOnePersistedOnOwnerUpdateAsync()
{
Owner owner = await (s.LoadAsync<Owner>(ownerId));

owner.Details = new Details()
owner.Details = new Details
{
Data = "Owner Details"
};
Expand All @@ -74,10 +74,10 @@ public async Task OneToOnePersistedOnOwnerUpdateForSessionUpdateAsync()
{
Owner owner;

using (var s = Sfi.OpenSession())
using (var s = OpenSession())
using (var tx = s.BeginTransaction())
{
owner = new Owner()
owner = new Owner
{
Name = "Owner",
};
Expand All @@ -95,7 +95,7 @@ public async Task OneToOnePersistedOnOwnerUpdateForSessionUpdateAsync()
using (var tx = s.BeginTransaction())
{
await (s.SaveOrUpdateAsync(owner));
owner.Details = new Details()
owner.Details = new Details
{
Data = "Owner Details"
};
Expand All @@ -110,5 +110,36 @@ public async Task OneToOnePersistedOnOwnerUpdateForSessionUpdateAsync()
Assert.IsNotNull(owner.Details);
}
}

[Test]
public async Task CanInsertByStatelessSessionAsync()
{
object id;

using (var s = Sfi.OpenStatelessSession())
using (var tx = s.BeginTransaction())
{
var details = new Details
{
Owner = new Owner
{
Name = "Owner"
},
Data = "Owner Details"
};

id = await (s.InsertAsync(details));

await (tx.CommitAsync());
}

using (var s = OpenSession())
using (s.BeginTransaction())
{
var owner = await (s.GetAsync<Owner>(id));

Assert.That(owner.Details, Is.Not.Null);
}
}
}
}
45 changes: 38 additions & 7 deletions src/NHibernate.Test/OneToOneType/Fixture.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ public class Fixture : BugTestCase
{
protected override void OnTearDown()
{
using (var s = Sfi.OpenSession())
using (var s = OpenSession())
using (var tx = s.BeginTransaction())
{
s.CreateQuery("delete from Details").ExecuteUpdate();
Expand All @@ -23,10 +23,10 @@ public void OneToOnePersistedOnOwnerUpdate()
{
object ownerId;

using (var s = Sfi.OpenSession())
using (var s = OpenSession())
using (var tx = s.BeginTransaction())
{
var owner = new Owner()
var owner = new Owner
{
Name = "Owner",
};
Expand All @@ -41,7 +41,7 @@ public void OneToOnePersistedOnOwnerUpdate()
{
Owner owner = s.Load<Owner>(ownerId);

owner.Details = new Details()
owner.Details = new Details
{
Data = "Owner Details"
};
Expand All @@ -63,10 +63,10 @@ public void OneToOnePersistedOnOwnerUpdateForSessionUpdate()
{
Owner owner;

using (var s = Sfi.OpenSession())
using (var s = OpenSession())
using (var tx = s.BeginTransaction())
{
owner = new Owner()
owner = new Owner
{
Name = "Owner",
};
Expand All @@ -84,7 +84,7 @@ public void OneToOnePersistedOnOwnerUpdateForSessionUpdate()
using (var tx = s.BeginTransaction())
{
s.SaveOrUpdate(owner);
owner.Details = new Details()
owner.Details = new Details
{
Data = "Owner Details"
};
Expand All @@ -99,5 +99,36 @@ public void OneToOnePersistedOnOwnerUpdateForSessionUpdate()
Assert.IsNotNull(owner.Details);
}
}

[Test]
public void CanInsertByStatelessSession()
{
object id;

using (var s = Sfi.OpenStatelessSession())
using (var tx = s.BeginTransaction())
{
var details = new Details
{
Owner = new Owner
{
Name = "Owner"
},
Data = "Owner Details"
};

id = s.Insert(details);

tx.Commit();
}

using (var s = OpenSession())
using (s.BeginTransaction())
{
var owner = s.Get<Owner>(id);

Assert.That(owner.Details, Is.Not.Null);
}
}
}
}
32 changes: 16 additions & 16 deletions src/NHibernate/Async/Id/ForeignGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
using System.Collections;
using System.Collections.Generic;
using NHibernate.Engine;
using NHibernate.Persister.Entity;
using NHibernate.Type;

namespace NHibernate.Id
Expand All @@ -36,8 +37,6 @@ public partial class ForeignGenerator : IIdentifierGenerator, IConfigurable
public async Task<object> GenerateAsync(ISessionImplementor sessionImplementor, object obj, CancellationToken cancellationToken)
{
cancellationToken.ThrowIfCancellationRequested();
ISession session = (ISession) sessionImplementor;

var persister = sessionImplementor.Factory.GetEntityPersister(entityName);
object associatedObject = persister.GetPropertyValue(obj, propertyName);

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

EntityType foreignValueSourceType;
IType propertyType = persister.GetPropertyType(propertyName);
if (propertyType.IsEntityType)
{
foreignValueSourceType = (EntityType) propertyType;
}
else
{
// try identifier mapper
foreignValueSourceType = (EntityType) persister.GetPropertyType("_identifierMapper." + propertyName);
}
var foreignValueSourceType = GetForeignValueSourceType(persister);

object id;
try
Expand All @@ -68,10 +57,21 @@ public async Task<object> GenerateAsync(ISessionImplementor sessionImplementor,
}
catch (TransientObjectException)
{
id = await (session.SaveAsync(foreignValueSourceType.GetAssociatedEntityName(), associatedObject, cancellationToken)).ConfigureAwait(false);
if (sessionImplementor is ISession session)
{
id = await (session.SaveAsync(foreignValueSourceType.GetAssociatedEntityName(), associatedObject, cancellationToken)).ConfigureAwait(false);
}
else if (sessionImplementor is IStatelessSession statelessSession)
{
id = await (statelessSession.InsertAsync(foreignValueSourceType.GetAssociatedEntityName(), associatedObject, cancellationToken)).ConfigureAwait(false);
}
else
{
throw new IdentifierGenerationException("sessionImplementor is neither Session nor StatelessSession");
}
}

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

#endregion
}
}
}
49 changes: 33 additions & 16 deletions src/NHibernate/Id/ForeignGenerator.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using System.Collections;
using System.Collections.Generic;
using NHibernate.Engine;
using NHibernate.Persister.Entity;
using NHibernate.Type;

namespace NHibernate.Id
Expand Down Expand Up @@ -39,8 +40,6 @@ public partial class ForeignGenerator : IIdentifierGenerator, IConfigurable
/// </returns>
public object Generate(ISessionImplementor sessionImplementor, object obj)
{
ISession session = (ISession) sessionImplementor;

var persister = sessionImplementor.Factory.GetEntityPersister(entityName);
object associatedObject = persister.GetPropertyValue(obj, propertyName);

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

EntityType foreignValueSourceType;
IType propertyType = persister.GetPropertyType(propertyName);
if (propertyType.IsEntityType)
{
foreignValueSourceType = (EntityType) propertyType;
}
else
{
// try identifier mapper
foreignValueSourceType = (EntityType) persister.GetPropertyType("_identifierMapper." + propertyName);
}
var foreignValueSourceType = GetForeignValueSourceType(persister);

object id;
try
Expand All @@ -71,10 +60,21 @@ public object Generate(ISessionImplementor sessionImplementor, object obj)
}
catch (TransientObjectException)
{
id = session.Save(foreignValueSourceType.GetAssociatedEntityName(), associatedObject);
if (sessionImplementor is ISession session)
{
id = session.Save(foreignValueSourceType.GetAssociatedEntityName(), associatedObject);
}
else if (sessionImplementor is IStatelessSession statelessSession)
{
id = statelessSession.Insert(foreignValueSourceType.GetAssociatedEntityName(), associatedObject);
}
else
{
throw new IdentifierGenerationException("sessionImplementor is neither Session nor StatelessSession");
}
}

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

private EntityType GetForeignValueSourceType(IEntityPersister persister)
{
var propertyType = persister.GetPropertyType(propertyName);
if (propertyType.IsEntityType)
{
return (EntityType) propertyType;
}

// try identifier mapper
return (EntityType) persister.GetPropertyType("_identifierMapper." + propertyName);
}

private static bool Contains(ISessionImplementor sessionImplementor, object obj)
{
return sessionImplementor is ISession session && session.Contains(obj);
}

#endregion

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

#endregion
}
}
}