Skip to content

Commit 62cf61f

Browse files
authored
Merge pull request #606 from hazzik/NH-3771
NH-3771 - Implement BatchVersionedData factory setting
2 parents e3c4267 + 82f0a84 commit 62cf61f

File tree

12 files changed

+178
-67
lines changed

12 files changed

+178
-67
lines changed

src/NHibernate.Test/NHSpecificTest/NH1553/MsSQL/SnapshotIsolationUpdateConflictTest.cs

Lines changed: 37 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
using System.Data;
2-
using System.Data.Common;
32
using NHibernate.Cfg;
43
using NHibernate.Dialect;
54
using NUnit.Framework;
5+
using NUnit.Framework.Constraints;
66

77
namespace NHibernate.Test.NHSpecificTest.NH1553.MsSQL
88
{
@@ -64,18 +64,15 @@ public void UpdateConflictDetectedByNH()
6464
p2.IdentificationNumber += 2;
6565

6666
SavePerson(p1);
67-
Assert.AreEqual(person.Version + 1, p1.Version);
68-
try
69-
{
70-
SavePerson(p2);
71-
Assert.Fail("Expecting stale object state exception");
72-
}
73-
catch (StaleObjectStateException sose)
74-
{
75-
Assert.AreEqual(typeof (Person).FullName, sose.EntityName);
76-
Assert.AreEqual(p2.Id, sose.Identifier);
77-
// as expected.
78-
}
67+
Assert.That(p1.Version, Is.EqualTo(person.Version + 1));
68+
69+
var expectedException = sessions.Settings.IsBatchVersionedDataEnabled
70+
? (IResolveConstraint) Throws.InstanceOf<StaleStateException>()
71+
: Throws.InstanceOf<StaleObjectStateException>()
72+
.And.Property("EntityName").EqualTo(typeof(Person).FullName)
73+
.And.Property("Identifier").EqualTo(p2.Id);
74+
75+
Assert.That(() => SavePerson(p2), expectedException);
7976
}
8077

8178
/// <summary>
@@ -89,46 +86,43 @@ public void UpdateConflictDetectedBySQLServer()
8986

9087
p1.IdentificationNumber++;
9188

92-
using (ISession session1 = OpenSession())
89+
using (var session1 = OpenSession())
90+
using (var tr1 = BeginTransaction(session1))
9391
{
94-
using (ITransaction tr1 = BeginTransaction(session1))
92+
session1.SaveOrUpdate(p1);
93+
session1.Flush();
94+
95+
using (var session2 = OpenSession())
96+
using (var tr2 = BeginTransaction(session2))
9597
{
96-
session1.SaveOrUpdate(p1);
97-
session1.Flush();
98+
var p2 = session2.Get<Person>(person.Id);
99+
p2.IdentificationNumber += 2;
100+
101+
tr1.Commit();
102+
Assert.That(p1.Version, Is.EqualTo(person.Version + 1));
103+
104+
session2.SaveOrUpdate(p2);
105+
106+
var expectedException = sessions.Settings.IsBatchVersionedDataEnabled
107+
? (IConstraint) Throws.InstanceOf<StaleStateException>()
108+
: Throws.InstanceOf<StaleObjectStateException>()
109+
.And.Property("EntityName").EqualTo(typeof(Person).FullName)
110+
.And.Property("Identifier").EqualTo(p2.Id);
98111

99-
using (ISession session2 = OpenSession())
100-
{
101-
using (ITransaction tr2 = BeginTransaction(session2))
112+
Assert.That(
113+
() =>
102114
{
103-
var p2 = session2.Get<Person>(person.Id);
104-
p2.IdentificationNumber += 2;
105-
106-
tr1.Commit();
107-
Assert.AreEqual(person.Version + 1, p1.Version);
108-
109-
try
110-
{
111-
session2.SaveOrUpdate(p2);
112-
session2.Flush();
113-
114-
tr2.Commit();
115-
Assert.Fail("StaleObjectStateException expected");
116-
}
117-
catch (StaleObjectStateException sose)
118-
{
119-
Assert.AreEqual(typeof (Person).FullName, sose.EntityName);
120-
Assert.AreEqual(p2.Id, sose.Identifier);
121-
// as expected
122-
}
123-
}
124-
}
115+
session2.Flush();
116+
tr2.Commit();
117+
},
118+
expectedException);
125119
}
126120
}
127121
}
128122

129123
protected override bool AppliesTo(Dialect.Dialect dialect)
130124
{
131-
return dialect is MsSql2005Dialect || dialect is MsSql2008Dialect;
125+
return dialect is MsSql2005Dialect;
132126
}
133127

134128
private void SetAllowSnapshotIsolation(bool on)
Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
using System.Collections;
2+
using NHibernate.AdoNet;
3+
using NHibernate.Cfg;
4+
using NUnit.Framework;
5+
6+
namespace NHibernate.Test.NHSpecificTest.NH3771
7+
{
8+
[TestFixture]
9+
public class Fixture : BugTestCase
10+
{
11+
protected override void Configure(Configuration configuration)
12+
{
13+
configuration.SetProperty(Environment.BatchVersionedData, "true");
14+
configuration.SetProperty(Environment.FormatSql, "false");
15+
configuration.SetProperty(Environment.GenerateStatistics, "true");
16+
configuration.SetProperty(Environment.BatchSize, "10");
17+
}
18+
19+
protected override bool AppliesTo(Engine.ISessionFactoryImplementor factory)
20+
{
21+
return !(factory.Settings.BatcherFactory is NonBatchingBatcherFactory);
22+
}
23+
24+
[Test]
25+
[Description("Should be two batchs with two sentences each.")]
26+
public void InsertAndUpdateWithBatch()
27+
{
28+
sessions.Statistics.Clear();
29+
30+
using (var sqlLog = new SqlLogSpy())
31+
using (ISession s = sessions.OpenSession())
32+
using (ITransaction tx = s.BeginTransaction())
33+
{
34+
Singer vs1 = new Singer();
35+
vs1.Id = 1;
36+
vs1.Name = "Fabrizio De Andre";
37+
s.Save(vs1);
38+
39+
Singer vs2 = new Singer();
40+
vs2.Id = 2;
41+
vs2.Name = "Vinicio Capossela";
42+
s.Save(vs2);
43+
44+
s.Flush();
45+
46+
vs1.Name = "De Andre, Fabrizio";
47+
vs2.Name = "Capossela, Vinicio";
48+
49+
s.Flush();
50+
51+
string log = sqlLog.GetWholeLog();
52+
53+
string[] separator = { System.Environment.NewLine };
54+
string[] lines = log.Split(separator, System.StringSplitOptions.RemoveEmptyEntries);
55+
56+
int batchs = 0;
57+
int sqls = 0;
58+
int batchCommands = 0;
59+
foreach (string line in lines)
60+
{
61+
if (line.StartsWith("NHibernate.SQL") && !line.StartsWith("NHibernate.SQL Batch commands:"))
62+
sqls++;
63+
64+
if (line.StartsWith("NHibernate.SQL Batch commands:"))
65+
batchs++;
66+
67+
if (line.StartsWith("command"))
68+
batchCommands++;
69+
}
70+
71+
Assert.AreEqual(2, batchs);
72+
Assert.AreEqual(0, sqls);
73+
Assert.AreEqual(4, batchCommands);
74+
Assert.AreEqual(2, sessions.Statistics.PrepareStatementCount);
75+
76+
tx.Rollback();
77+
}
78+
}
79+
}
80+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
<?xml version="1.0" encoding="utf-8" ?>
2+
<hibernate-mapping
3+
xmlns="urn:nhibernate-mapping-2.2"
4+
assembly="NHibernate.Test"
5+
namespace="NHibernate.Test.NHSpecificTest.NH3771">
6+
7+
<class name="Singer">
8+
<id name="Id"/>
9+
<version name="Version"/>
10+
<property name="Name" type="String" />
11+
</class>
12+
13+
14+
</hibernate-mapping>
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
using System;
2+
using System.Collections.Generic;
3+
4+
namespace NHibernate.Test.NHSpecificTest.NH3771
5+
{
6+
public class Singer
7+
{
8+
public virtual long Id { get; set; }
9+
public virtual string Name { get; set; }
10+
public virtual int Version { get; set; }
11+
}
12+
}

src/NHibernate.Test/NHSpecificTest/OptimisticConcurrencyFixture.cs

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,12 @@ public void StaleObjectStateCheckWithNormalizedEntityPersister()
5555
}
5656

5757
top.Name = "new name";
58-
Assert.Throws<StaleObjectStateException>(() => session.Flush());
58+
59+
var expectedException = sessions.Settings.IsBatchVersionedDataEnabled
60+
? Throws.InstanceOf<StaleStateException>()
61+
: Throws.InstanceOf<StaleObjectStateException>();
62+
63+
Assert.That(() => session.Flush(), expectedException);
5964
}
6065
}
6166
finally
@@ -89,7 +94,12 @@ public void StaleObjectStateCheckWithEntityPersisterAndOptimisticLock()
8994
}
9095

9196
optimistic.String = "new string";
92-
Assert.Throws<StaleObjectStateException>(() => session.Flush());
97+
98+
var expectedException = sessions.Settings.IsBatchVersionedDataEnabled
99+
? Throws.InstanceOf<StaleStateException>()
100+
: Throws.InstanceOf<StaleObjectStateException>();
101+
102+
Assert.That(() => session.Flush(), expectedException);
93103
}
94104
}
95105
finally

src/NHibernate.Test/NHibernate.Test.csproj

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -959,6 +959,8 @@
959959
<Compile Include="NHSpecificTest\NH3634\PersonMapper.cs" />
960960
<Compile Include="NHSpecificTest\NH3727\Entity.cs" />
961961
<Compile Include="NHSpecificTest\NH3727\FixtureByCode.cs" />
962+
<Compile Include="NHSpecificTest\NH3771\Fixture.cs" />
963+
<Compile Include="NHSpecificTest\NH3771\Model.cs" />
962964
<Compile Include="NHSpecificTest\NH3795\Fixture.cs" />
963965
<Compile Include="NHSpecificTest\NH3844\Domain.cs" />
964966
<Compile Include="NHSpecificTest\NH3844\Fixture.cs" />
@@ -3269,6 +3271,7 @@
32693271
<EmbeddedResource Include="NHSpecificTest\NH2204\Mappings.hbm.xml" />
32703272
<EmbeddedResource Include="NHSpecificTest\NH3874\Mappings.hbm.xml" />
32713273
<EmbeddedResource Include="NHSpecificTest\EntityWithUserTypeCanHaveLinqGenerators\Mappings.hbm.xml" />
3274+
<EmbeddedResource Include="NHSpecificTest\NH3771\Mappings.hbm.xml" />
32723275
<EmbeddedResource Include="NHSpecificTest\NH2218\Mappings.hbm.xml" />
32733276
<EmbeddedResource Include="NHSpecificTest\NH3046\Mappings.hbm.xml" />
32743277
<EmbeddedResource Include="NHSpecificTest\NH3518\Mappings.hbm.xml" />

src/NHibernate.Test/VersionTest/Db/MsSQL/GeneratedBinaryVersionFixture.cs

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -86,26 +86,26 @@ public void ShouldCheckStaleState()
8686

8787
try
8888
{
89-
using (ISession session = OpenSession())
89+
using (var session = OpenSession())
9090
{
9191
session.Save(versioned);
9292
session.Flush();
9393

94-
using (ISession concurrentSession = OpenSession())
94+
using (var concurrentSession = OpenSession())
9595
{
9696
var sameVersioned = concurrentSession.Get<SimpleVersioned>(versioned.Id);
9797
sameVersioned.Something = "another string";
9898
concurrentSession.Flush();
9999
}
100100

101101
versioned.Something = "new string";
102-
session.Flush();
102+
103+
var expectedException = sessions.Settings.IsBatchVersionedDataEnabled
104+
? Throws.InstanceOf<StaleStateException>()
105+
: Throws.InstanceOf<StaleObjectStateException>();
106+
107+
Assert.That(() => session.Flush(), expectedException);
103108
}
104-
Assert.Fail("Expected exception was not thrown");
105-
}
106-
catch (StaleObjectStateException)
107-
{
108-
// as expected
109109
}
110110
finally
111111
{

src/NHibernate/Cfg/Environment.cs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -113,8 +113,6 @@ public static string Version
113113
// Unused, not implemented
114114
public const string StatementFetchSize = "jdbc.fetch_size";
115115

116-
public const string BatchVersionedData = "jdbc.batch_versioned_data";
117-
118116
// Unused, not implemented
119117
public const string OutputStylesheet = "xml.output_stylesheet";
120118

@@ -154,6 +152,7 @@ public static string Version
154152
// Unused, not implemented
155153
public const string SqlExceptionConverter = "sql_exception_converter";
156154

155+
public const string BatchVersionedData = "adonet.batch_versioned_data";
157156
public const string WrapResultSets = "adonet.wrap_result_sets";
158157
public const string BatchSize = "adonet.batch_size";
159158
public const string BatchStrategy = "adonet.factory_class";

src/NHibernate/Cfg/Settings.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,6 @@ public Settings()
2929
#region JDBC Specific (Not Ported)
3030

3131
//private int jdbcFetchSize;
32-
//private bool isJdbcBatchVersionedData;
3332

3433
#endregion
3534
public SqlStatementLogger SqlStatementLogger { get; internal set; }
@@ -118,6 +117,8 @@ public Settings()
118117

119118
public bool IsNamedQueryStartupCheckingEnabled { get; internal set; }
120119

120+
public bool IsBatchVersionedDataEnabled { get; internal set; }
121+
121122
#region NH specific
122123

123124
public IsolationLevel IsolationLevel { get; internal set; }

src/NHibernate/Cfg/SettingsFactory.cs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -230,7 +230,6 @@ public Settings BuildSettings(IDictionary<string, string> properties)
230230

231231
//ADO.NET and connection settings:
232232

233-
// TODO: Environment.BatchVersionedData
234233
settings.AdoBatchSize = PropertiesHelper.GetInt32(Environment.BatchSize, properties, 0);
235234
bool orderInserts = PropertiesHelper.GetBoolean(Environment.OrderInserts, properties, (settings.AdoBatchSize > 0));
236235
log.Info("Order SQL inserts for batching: " + EnabledDisabled(orderInserts));
@@ -243,6 +242,11 @@ public Settings BuildSettings(IDictionary<string, string> properties)
243242
bool wrapResultSets = PropertiesHelper.GetBoolean(Environment.WrapResultSets, properties, false);
244243
log.Debug("Wrap result sets: " + EnabledDisabled(wrapResultSets));
245244
settings.IsWrapResultSetsEnabled = wrapResultSets;
245+
246+
bool batchVersionedData = PropertiesHelper.GetBoolean(Environment.BatchVersionedData, properties, false);
247+
log.Debug("Batch versioned data: " + EnabledDisabled(batchVersionedData));
248+
settings.IsBatchVersionedDataEnabled = batchVersionedData;
249+
246250
settings.BatcherFactory = CreateBatcherFactory(properties, settings.AdoBatchSize, connectionProvider);
247251

248252
string isolationString = PropertiesHelper.GetString(Environment.Isolation, properties, String.Empty);

src/NHibernate/Persister/Entity/AbstractEntityPersister.cs

Lines changed: 3 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -616,16 +616,9 @@ protected SqlString VersionSelectString
616616
get { return sqlVersionSelectString; }
617617
}
618618

619-
public bool IsBatchable
620-
{
621-
get
622-
{
623-
return
624-
OptimisticLockMode == Versioning.OptimisticLock.None
625-
|| (!IsVersioned && OptimisticLockMode == Versioning.OptimisticLock.Version);
626-
//|| Factory.Settings.IsJdbcBatchVersionedData();
627-
}
628-
}
619+
public bool IsBatchable => OptimisticLockMode == Versioning.OptimisticLock.None ||
620+
(!IsVersioned && OptimisticLockMode == Versioning.OptimisticLock.Version) ||
621+
Factory.Settings.IsBatchVersionedDataEnabled;
629622

630623
public virtual string[] QuerySpaces
631624
{

src/NHibernate/nhibernate-configuration.xsd

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,7 @@
121121
<xs:enumeration value="query.query_model_rewriter_factory" />
122122
<xs:enumeration value="linqtohql.generatorsregistry" />
123123
<xs:enumeration value="odbc.explicit_datetime_scale" />
124+
<xs:enumeration value="adonet.batch_versioned_data" />
124125
</xs:restriction>
125126
</xs:simpleType>
126127
</xs:attribute>

0 commit comments

Comments
 (0)