Skip to content

Commit 4241a4b

Browse files
committed
Fixes #3421
1 parent b4f8b01 commit 4241a4b

File tree

3 files changed

+118
-16
lines changed

3 files changed

+118
-16
lines changed
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.GH3421
5+
{
6+
class Entity
7+
{
8+
public virtual Guid Id { get; set; }
9+
public virtual string Name { get; set; }
10+
11+
private IDictionary<string, object> _attributes;
12+
public virtual IDictionary<string, object> Attributes {
13+
get {
14+
if (_attributes == null)
15+
_attributes = new Dictionary<string, object>();
16+
return _attributes;
17+
}
18+
set => _attributes = value;
19+
}
20+
}
21+
}
Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
using System.Collections.Generic;
2+
using System.Linq;
3+
using NHibernate.Cfg;
4+
using NHibernate.Cfg.MappingSchema;
5+
using NHibernate.Mapping.ByCode;
6+
using NHibernate.SqlCommand;
7+
using NUnit.Framework;
8+
9+
namespace NHibernate.Test.NHSpecificTest.GH3421
10+
{
11+
[TestFixture]
12+
public class ByCodeFixture : TestCaseMappingByCode
13+
{
14+
private SqlInterceptor _interceptor;
15+
16+
protected override HbmMapping GetMappings()
17+
{
18+
var mapper = new ModelMapper();
19+
mapper.Class<Entity>(rc =>
20+
{
21+
rc.Id(x => x.Id, m => m.Generator(Generators.GuidComb));
22+
rc.Property(x => x.Name);
23+
rc.Component(x => x.Attributes, new {
24+
Sku = (string)null
25+
}, dc => {
26+
dc.Property(x => x.Sku);
27+
});
28+
});
29+
30+
return mapper.CompileMappingForAllExplicitlyAddedEntities();
31+
}
32+
33+
protected override void Configure(Configuration configuration)
34+
{
35+
base.Configure(configuration);
36+
37+
_interceptor = new SqlInterceptor();
38+
39+
configuration.SetInterceptor(_interceptor);
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", Attributes = new Dictionary<string, object>() {
51+
{ "Sku", "AAA" }
52+
} };
53+
session.Save(e2);
54+
55+
transaction.Commit();
56+
}
57+
}
58+
59+
protected override void OnTearDown()
60+
{
61+
using (var session = OpenSession())
62+
using (var transaction = session.BeginTransaction())
63+
{
64+
session.CreateQuery("delete from Entity").ExecuteUpdate();
65+
transaction.Commit();
66+
}
67+
}
68+
69+
[Test]
70+
public void TestFlushDoesNotTriggerAnUpdate()
71+
{
72+
using (var session = OpenSession())
73+
using (var transaction = session.BeginTransaction())
74+
{
75+
var foo = session.Query<Entity>().ToList();
76+
77+
session.Flush();
78+
79+
var updateStatements = _interceptor.SqlStatements.Where(s => s.ToString().ToUpper().Contains("UPDATE")).ToList();
80+
81+
Assert.That(updateStatements, Has.Count.EqualTo(0));
82+
}
83+
}
84+
85+
public class SqlInterceptor : EmptyInterceptor
86+
{
87+
public IList<SqlString> SqlStatements = new List<SqlString>();
88+
89+
public override SqlString OnPrepareStatement(SqlString sql)
90+
{
91+
SqlStatements.Add(sql);
92+
93+
return base.OnPrepareStatement(sql);
94+
}
95+
}
96+
}
97+
}

src/NHibernate/Type/ComponentType.cs

Lines changed: 0 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -156,14 +156,6 @@ public override bool IsDirty(object x, object y, ISessionImplementor session)
156156
{
157157
return false;
158158
}
159-
/*
160-
* NH Different behavior : we don't use the shortcut because NH-1101
161-
* let the tuplizer choose how cosiderer properties when the component is null.
162-
*/
163-
if (EntityMode != EntityMode.Poco && (x == null || y == null))
164-
{
165-
return true;
166-
}
167159
object[] xvalues = GetPropertyValues(x);
168160
object[] yvalues = GetPropertyValues(y);
169161
for (int i = 0; i < xvalues.Length; i++)
@@ -182,14 +174,6 @@ public override bool IsDirty(object x, object y, bool[] checkable, ISessionImple
182174
{
183175
return false;
184176
}
185-
/*
186-
* NH Different behavior : we don't use the shortcut because NH-1101
187-
* let the tuplizer choose how cosiderer properties when the component is null.
188-
*/
189-
if (EntityMode != EntityMode.Poco && (x == null || y == null))
190-
{
191-
return true;
192-
}
193177
object[] xvalues = GetPropertyValues(x);
194178
object[] yvalues = GetPropertyValues(y);
195179
int loc = 0;

0 commit comments

Comments
 (0)