Skip to content

Commit 9339720

Browse files
committed
Merge branch 'ggeurts-NH-3372'
2 parents 9a91dbb + ba21fbb commit 9339720

File tree

5 files changed

+132
-7
lines changed

5 files changed

+132
-7
lines changed
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
namespace NHibernate.Test.NHSpecificTest.NH3372
2+
{
3+
public class Entity
4+
{
5+
public int Id { get; set; }
6+
public string ShardId { get; set; }
7+
public string Content { get; set; }
8+
}
9+
}
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
using NUnit.Framework;
2+
3+
namespace NHibernate.Test.NHSpecificTest.NH3372
4+
{
5+
[TestFixture]
6+
public class Fixture : BugTestCase
7+
{
8+
protected override bool AppliesTo(Dialect.Dialect dialect)
9+
{
10+
return dialect is NHibernate.Dialect.MsSql2000Dialect;
11+
}
12+
13+
[Test]
14+
public void CanGeneratePropertyOnInsertOfEntityWithCustomLoader()
15+
{
16+
using (var session = OpenSession())
17+
using (session.BeginTransaction())
18+
{
19+
var entity = new Entity { Content = "Some text" };
20+
session.Save(entity);
21+
session.Flush();
22+
23+
Assert.That(entity.ShardId, Is.Not.Null & Has.Length.GreaterThan(0));
24+
}
25+
}
26+
27+
[Test]
28+
public void CanGeneratePropertyOnUpdateOfEntityWithCustomLoader()
29+
{
30+
using (var session = OpenSession())
31+
using (session.BeginTransaction())
32+
{
33+
var entity = new Entity { Content = "Some text" };
34+
session.Save(entity);
35+
session.Flush();
36+
37+
entity.ShardId = null;
38+
entity.Content = "Some other text";
39+
session.Update(entity);
40+
session.Flush();
41+
42+
Assert.That(entity.ShardId, Is.Not.Null & Has.Length.GreaterThan(0));
43+
}
44+
}
45+
46+
}
47+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"
3+
assembly="NHibernate.Test"
4+
namespace="NHibernate.Test.NHSpecificTest.NH3372">
5+
6+
<class name="Entity" table="entity" lazy="false">
7+
<id name="Id" column="id" generator="native" />
8+
<property name="ShardId" generated="always" insert="false" update="false" />
9+
<property name="Content" column="content" />
10+
<loader query-ref="LoadEntity" />
11+
</class>
12+
13+
<sql-query name="LoadEntity" xml:space="preserve">
14+
<return class="Entity" alias="e" />
15+
SELECT id AS {e.Id}
16+
, DB_NAME() AS {e.ShardId}
17+
, content AS {e.Content}
18+
FROM entity
19+
WHERE id = ?
20+
</sql-query>
21+
</hibernate-mapping>

src/NHibernate.Test/NHibernate.Test.csproj

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -713,6 +713,8 @@
713713
<Compile Include="NHSpecificTest\BagWithLazyExtraAndFilter\Fixture.cs" />
714714
<Compile Include="Linq\ByMethod\DistinctTests.cs" />
715715
<Compile Include="Component\Basic\ComponentWithUniqueConstraintTests.cs" />
716+
<Compile Include="NHSpecificTest\NH3372\Entity.cs" />
717+
<Compile Include="NHSpecificTest\NH3372\Fixture.cs" />
716718
<Compile Include="NHSpecificTest\NH3487\Entity.cs" />
717719
<Compile Include="NHSpecificTest\NH3487\Fixture.cs" />
718720
<Compile Include="NHSpecificTest\NH3570\BiFixture.cs" />
@@ -3104,6 +3106,7 @@
31043106
</ItemGroup>
31053107
<ItemGroup>
31063108
<EmbeddedResource Include="LazyComponentTest\Person.hbm.xml" />
3109+
<Content Include="NHSpecificTest\NH3372\Mappings.hbm.xml" />
31073110
<EmbeddedResource Include="NHSpecificTest\NH3570\Mappings.hbm.xml" />
31083111
<EmbeddedResource Include="NHSpecificTest\NH3455\Mappings.hbm.xml" />
31093112
<EmbeddedResource Include="NHSpecificTest\NH3590\Mappings.hbm.xml" />

src/NHibernate/Persister/Entity/AbstractEntityPersister.cs

Lines changed: 52 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4026,7 +4026,23 @@ public void ProcessInsertGeneratedProperties(object id, object entity, object[]
40264026
{
40274027
throw new AssertionFailure("no insert-generated properties");
40284028
}
4029-
ProcessGeneratedProperties(id, entity, state, session, sqlInsertGeneratedValuesSelectString, PropertyInsertGenerationInclusions);
4029+
4030+
session.Batcher.ExecuteBatch(); //force immediate execution of the insert
4031+
4032+
if (loaderName == null)
4033+
{
4034+
ProcessGeneratedPropertiesWithGeneratedSql(id, entity, state, session, sqlInsertGeneratedValuesSelectString, PropertyInsertGenerationInclusions);
4035+
}
4036+
else
4037+
{
4038+
ProcessGeneratedPropertiesWithLoader(id, entity, session);
4039+
4040+
// The loader has added the entity to the first-level cache. We must remove
4041+
// the entity from the first-level cache to avoid problems in the Save or SaveOrUpdate
4042+
// event listeners, which don't expect the entity to already be present in the
4043+
// first-level cache.
4044+
session.PersistenceContext.RemoveEntity(session.GenerateEntityKey(id, this));
4045+
}
40304046
}
40314047

40324048
public void ProcessUpdateGeneratedProperties(object id, object entity, object[] state, ISessionImplementor session)
@@ -4035,14 +4051,25 @@ public void ProcessUpdateGeneratedProperties(object id, object entity, object[]
40354051
{
40364052
throw new AssertionFailure("no update-generated properties");
40374053
}
4038-
ProcessGeneratedProperties(id, entity, state, session, sqlUpdateGeneratedValuesSelectString, PropertyUpdateGenerationInclusions);
4054+
4055+
session.Batcher.ExecuteBatch(); //force immediate execution of the update
4056+
4057+
if (loaderName == null)
4058+
{
4059+
ProcessGeneratedPropertiesWithGeneratedSql(id, entity, state, session, sqlUpdateGeneratedValuesSelectString, PropertyUpdateGenerationInclusions);
4060+
}
4061+
else
4062+
{
4063+
// Remove entity from first-level cache to ensure that loader fetches fresh data from database.
4064+
// The loader will ensure that the same entity is added back to the first-level cache.
4065+
session.PersistenceContext.RemoveEntity(session.GenerateEntityKey(id, this));
4066+
ProcessGeneratedPropertiesWithLoader(id, entity, session);
4067+
}
40394068
}
40404069

4041-
private void ProcessGeneratedProperties(object id, object entity, object[] state,
4042-
ISessionImplementor session, SqlString selectionSQL, ValueInclusion[] includeds)
4070+
private void ProcessGeneratedPropertiesWithGeneratedSql(object id, object entity, object[] state,
4071+
ISessionImplementor session, SqlString selectionSQL, ValueInclusion[] generationInclusions)
40434072
{
4044-
session.Batcher.ExecuteBatch(); //force immediate execution of the insert
4045-
40464073
using (new SessionIdLoggingContext(session.SessionId))
40474074
try
40484075
{
@@ -4060,7 +4087,7 @@ private void ProcessGeneratedProperties(object id, object entity, object[] state
40604087
}
40614088
for (int i = 0; i < PropertySpan; i++)
40624089
{
4063-
if (includeds[i] != ValueInclusion.None)
4090+
if (generationInclusions[i] != ValueInclusion.None)
40644091
{
40654092
object hydratedState = PropertyTypes[i].Hydrate(rs, GetPropertyAliases(string.Empty, i), session, entity);
40664093
state[i] = PropertyTypes[i].ResolveIdentifier(hydratedState, session, entity);
@@ -4087,6 +4114,24 @@ private void ProcessGeneratedProperties(object id, object entity, object[] state
40874114
}
40884115
}
40894116

4117+
private void ProcessGeneratedPropertiesWithLoader(object id, object entity, ISessionImplementor session)
4118+
{
4119+
var query = (AbstractQueryImpl)session.GetNamedQuery(loaderName);
4120+
if (query.HasNamedParameters)
4121+
{
4122+
query.SetParameter(query.NamedParameters[0], id, this.IdentifierType);
4123+
}
4124+
else
4125+
{
4126+
query.SetParameter(0, id, this.IdentifierType);
4127+
}
4128+
query.SetOptionalId(id);
4129+
query.SetOptionalEntityName(this.EntityName);
4130+
query.SetOptionalObject(entity);
4131+
query.SetFlushMode(FlushMode.Never);
4132+
query.List();
4133+
}
4134+
40904135
public bool HasSubselectLoadableCollections
40914136
{
40924137
get { return hasSubselectLoadableCollections; }

0 commit comments

Comments
 (0)