diff --git a/src/NHibernate.Test/Async/NHSpecificTest/GH2631/Fixture.cs b/src/NHibernate.Test/Async/NHSpecificTest/GH2631/Fixture.cs
new file mode 100644
index 00000000000..4c720bcede1
--- /dev/null
+++ b/src/NHibernate.Test/Async/NHSpecificTest/GH2631/Fixture.cs
@@ -0,0 +1,88 @@
+//------------------------------------------------------------------------------
+//
+// This code was generated by AsyncGenerator.
+//
+// Changes to this file may cause incorrect behavior and will be lost if
+// the code is regenerated.
+//
+//------------------------------------------------------------------------------
+
+
+using System.Linq;
+using NUnit.Framework;
+using NHibernate.Linq;
+
+namespace NHibernate.Test.NHSpecificTest.GH2631
+{
+ using System.Threading.Tasks;
+ [TestFixture]
+ public class FixtureAsync : BugTestCase
+ {
+ protected override void OnSetUp()
+ {
+ using (var session = OpenSession())
+ using (var transaction = session.BeginTransaction())
+ {
+ var person = new Person
+ {
+ Name = "Testing"
+ };
+ person.Address = new Address
+ {
+ Person = person,
+ Street = "Mulberry"
+ };
+ session.Save(person);
+
+ transaction.Commit();
+ }
+ }
+
+ protected override void OnTearDown()
+ {
+ using (var session = OpenSession())
+ using (var transaction = session.BeginTransaction())
+ {
+ session.CreateQuery("delete from Address").ExecuteUpdate();
+ session.CreateQuery("delete from System.Object").ExecuteUpdate();
+
+ transaction.Commit();
+ }
+ }
+
+ [Test]
+ public async Task IndexOutOfRangeOnDeleteAsync()
+ {
+ using (var session = OpenSession())
+ using (var t = session.BeginTransaction())
+ {
+ var persons = await (session.Query().ToListAsync());
+
+ foreach (var person in persons)
+ {
+ await (session.DeleteAsync(person));
+ }
+
+ await (t.CommitAsync());
+ }
+ }
+
+ [Test]
+ public async Task UpdateAsync()
+ {
+ using (var session = OpenSession())
+ using (var t = session.BeginTransaction())
+ {
+ var persons = await (session.Query().ToListAsync());
+
+ foreach (var person in persons)
+ {
+ person.Name = "x";
+ person.Address = null;
+ }
+
+ await (t.CommitAsync());
+ }
+ }
+ }
+}
diff --git a/src/NHibernate.Test/NHSpecificTest/GH2631/Address.cs b/src/NHibernate.Test/NHSpecificTest/GH2631/Address.cs
new file mode 100644
index 00000000000..431cf1915cb
--- /dev/null
+++ b/src/NHibernate.Test/NHSpecificTest/GH2631/Address.cs
@@ -0,0 +1,13 @@
+using System;
+
+namespace NHibernate.Test.NHSpecificTest.GH2631
+{
+ public class Address
+ {
+ public virtual Guid Id { get; set; }
+
+ public virtual Person Person { get; set; }
+
+ public virtual string Street { get; set; }
+ }
+}
diff --git a/src/NHibernate.Test/NHSpecificTest/GH2631/Fixture.cs b/src/NHibernate.Test/NHSpecificTest/GH2631/Fixture.cs
new file mode 100644
index 00000000000..447bf61ae4e
--- /dev/null
+++ b/src/NHibernate.Test/NHSpecificTest/GH2631/Fixture.cs
@@ -0,0 +1,76 @@
+using System.Linq;
+using NUnit.Framework;
+
+namespace NHibernate.Test.NHSpecificTest.GH2631
+{
+ [TestFixture]
+ public class Fixture : BugTestCase
+ {
+ protected override void OnSetUp()
+ {
+ using (var session = OpenSession())
+ using (var transaction = session.BeginTransaction())
+ {
+ var person = new Person
+ {
+ Name = "Testing"
+ };
+ person.Address = new Address
+ {
+ Person = person,
+ Street = "Mulberry"
+ };
+ session.Save(person);
+
+ transaction.Commit();
+ }
+ }
+
+ protected override void OnTearDown()
+ {
+ using (var session = OpenSession())
+ using (var transaction = session.BeginTransaction())
+ {
+ session.CreateQuery("delete from Address").ExecuteUpdate();
+ session.CreateQuery("delete from System.Object").ExecuteUpdate();
+
+ transaction.Commit();
+ }
+ }
+
+ [Test]
+ public void IndexOutOfRangeOnDelete()
+ {
+ using (var session = OpenSession())
+ using (var t = session.BeginTransaction())
+ {
+ var persons = session.Query().ToList();
+
+ foreach (var person in persons)
+ {
+ session.Delete(person);
+ }
+
+ t.Commit();
+ }
+ }
+
+ [Test]
+ public void Update()
+ {
+ using (var session = OpenSession())
+ using (var t = session.BeginTransaction())
+ {
+ var persons = session.Query().ToList();
+
+ foreach (var person in persons)
+ {
+ person.Name = "x";
+ person.Address = null;
+ }
+
+ t.Commit();
+ }
+ }
+ }
+}
diff --git a/src/NHibernate.Test/NHSpecificTest/GH2631/Mappings.hbm.xml b/src/NHibernate.Test/NHSpecificTest/GH2631/Mappings.hbm.xml
new file mode 100644
index 00000000000..a2540a5ddca
--- /dev/null
+++ b/src/NHibernate.Test/NHSpecificTest/GH2631/Mappings.hbm.xml
@@ -0,0 +1,26 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Person
+
+
+
+
+
+
+
+
diff --git a/src/NHibernate.Test/NHSpecificTest/GH2631/Person.cs b/src/NHibernate.Test/NHSpecificTest/GH2631/Person.cs
new file mode 100644
index 00000000000..60b21d067ce
--- /dev/null
+++ b/src/NHibernate.Test/NHSpecificTest/GH2631/Person.cs
@@ -0,0 +1,13 @@
+using System;
+
+namespace NHibernate.Test.NHSpecificTest.GH2631
+{
+ public class Person
+ {
+ public virtual Guid Id { get; set; }
+
+ public virtual string Name { get; set; }
+
+ public virtual Address Address { get; set; }
+ }
+}
diff --git a/src/NHibernate/Async/Persister/Entity/AbstractEntityPersister.cs b/src/NHibernate/Async/Persister/Entity/AbstractEntityPersister.cs
index 09f2076dd3d..bb79a22e7f6 100644
--- a/src/NHibernate/Async/Persister/Entity/AbstractEntityPersister.cs
+++ b/src/NHibernate/Async/Persister/Entity/AbstractEntityPersister.cs
@@ -896,7 +896,7 @@ public async Task DeleteAsync(object id, object version, int j, object obj, SqlC
IType[] types = PropertyTypes;
for (int i = 0; i < entityMetamodel.PropertySpan; i++)
{
- if (IsPropertyOfTable(i, j) && versionability[i])
+ if (IsPropertyOfTable(i, j) && versionability[i] && types[i].GetOwnerColumnSpan(Factory) > 0)
{
// this property belongs to the table and it is not specifically
// excluded from optimistic locking by optimistic-lock="false"
diff --git a/src/NHibernate/Persister/Entity/AbstractEntityPersister.cs b/src/NHibernate/Persister/Entity/AbstractEntityPersister.cs
index 78afb6e2b09..43f8403143b 100644
--- a/src/NHibernate/Persister/Entity/AbstractEntityPersister.cs
+++ b/src/NHibernate/Persister/Entity/AbstractEntityPersister.cs
@@ -3347,7 +3347,7 @@ public void Delete(object id, object version, int j, object obj, SqlCommandInfo
IType[] types = PropertyTypes;
for (int i = 0; i < entityMetamodel.PropertySpan; i++)
{
- if (IsPropertyOfTable(i, j) && versionability[i])
+ if (IsPropertyOfTable(i, j) && versionability[i] && types[i].GetOwnerColumnSpan(Factory) > 0)
{
// this property belongs to the table and it is not specifically
// excluded from optimistic locking by optimistic-lock="false"
@@ -3583,13 +3583,13 @@ protected SqlCommandInfo[] GenerateSQLDeleteStrings(object[] loadedState)
{
delete.SetComment("delete " + EntityName + " [" + j + "]");
}
-
bool[] versionability = PropertyVersionability;
IType[] types = PropertyTypes;
for (int i = 0; i < entityMetamodel.PropertySpan; i++)
{
bool include = versionability[i] &&
- IsPropertyOfTable(i, j);
+ IsPropertyOfTable(i, j)
+ && types[i].GetOwnerColumnSpan(Factory) > 0;
if (include)
{