Skip to content

Commit 9de4aaa

Browse files
RogerKratzfredericDelaporte
authored andcommitted
Test Merging a bidirectonal list creates unecessary UPDATE statement (#1531)
Add test for issue #1530
1 parent a9a728b commit 9de4aaa

File tree

5 files changed

+337
-0
lines changed

5 files changed

+337
-0
lines changed
Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
//------------------------------------------------------------------------------
2+
// <auto-generated>
3+
// This code was generated by AsyncGenerator.
4+
//
5+
// Changes to this file may cause incorrect behavior and will be lost if
6+
// the code is regenerated.
7+
// </auto-generated>
8+
//------------------------------------------------------------------------------
9+
10+
11+
using NHibernate.Cfg;
12+
using NUnit.Framework;
13+
using Environment = NHibernate.Cfg.Environment;
14+
15+
namespace NHibernate.Test.NHSpecificTest.GH1530
16+
{
17+
using System.Threading.Tasks;
18+
[TestFixture]
19+
public abstract class FixtureBaseAsync : BugTestCase
20+
{
21+
private Parent _parent;
22+
23+
protected override void OnSetUp()
24+
{
25+
using (var s = OpenSession())
26+
{
27+
using (var tx = s.BeginTransaction())
28+
{
29+
_parent = new Parent();
30+
_parent.AddChild(new Child());
31+
s.Save(_parent);
32+
tx.Commit();
33+
}
34+
}
35+
}
36+
37+
[Test]
38+
public virtual async Task OneNewChildShouldOnlyCreateInsertWithNoUpdate_LockAndMergeAsync()
39+
{
40+
var parentClone = _parent.MakeCopy();
41+
parentClone.AddChild(new Child());
42+
using (var s = OpenSession())
43+
{
44+
using (var tx = s.BeginTransaction())
45+
{
46+
await (s.LockAsync(_parent, LockMode.None));
47+
await (s.MergeAsync(parentClone));
48+
s.SessionFactory.Statistics.Clear();
49+
await (tx.CommitAsync());
50+
}
51+
52+
Assert.That(s.SessionFactory.Statistics.PrepareStatementCount, Is.EqualTo(1));
53+
}
54+
}
55+
56+
[Test]
57+
public virtual async Task OneNewChildShouldOnlyCreateInsertWithNoUpdate_MergeAsync()
58+
{
59+
var parentClone = _parent.MakeCopy();
60+
parentClone.AddChild(new Child());
61+
using (var s = OpenSession())
62+
{
63+
using (var tx = s.BeginTransaction())
64+
{
65+
await (s.MergeAsync(parentClone));
66+
s.SessionFactory.Statistics.Clear();
67+
await (tx.CommitAsync());
68+
}
69+
70+
Assert.That(s.SessionFactory.Statistics.PrepareStatementCount, Is.EqualTo(1));
71+
}
72+
}
73+
74+
protected override void OnTearDown()
75+
{
76+
using (var s = OpenSession())
77+
{
78+
using (var tx = s.BeginTransaction())
79+
{
80+
s.Delete(s.Load<Parent>(_parent.Id));
81+
tx.Commit();
82+
}
83+
}
84+
}
85+
86+
protected override void Configure(Configuration configuration)
87+
{
88+
configuration.SetProperty(Environment.GenerateStatistics, "true");
89+
}
90+
}
91+
92+
[TestFixture]
93+
public class FixtureAsync : FixtureBaseAsync
94+
{
95+
[Test]
96+
[KnownBug("#1530")]
97+
public override async Task OneNewChildShouldOnlyCreateInsertWithNoUpdate_MergeAsync()
98+
{
99+
await (base.OneNewChildShouldOnlyCreateInsertWithNoUpdate_MergeAsync());
100+
}
101+
102+
[Test]
103+
[KnownBug("#1530")]
104+
public override async Task OneNewChildShouldOnlyCreateInsertWithNoUpdate_LockAndMergeAsync()
105+
{
106+
await (base.OneNewChildShouldOnlyCreateInsertWithNoUpdate_LockAndMergeAsync());
107+
}
108+
}
109+
110+
[TestFixture]
111+
public class NonInverseFixtureAsync : FixtureBaseAsync
112+
{
113+
protected override string[] Mappings => new[] { "NonInverseMappings.hbm.xml" };
114+
}
115+
116+
}
Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
using NHibernate.Cfg;
2+
using NUnit.Framework;
3+
using Environment = NHibernate.Cfg.Environment;
4+
5+
namespace NHibernate.Test.NHSpecificTest.GH1530
6+
{
7+
[TestFixture]
8+
public abstract class FixtureBase : BugTestCase
9+
{
10+
private Parent _parent;
11+
12+
protected override void OnSetUp()
13+
{
14+
using (var s = OpenSession())
15+
{
16+
using (var tx = s.BeginTransaction())
17+
{
18+
_parent = new Parent();
19+
_parent.AddChild(new Child());
20+
s.Save(_parent);
21+
tx.Commit();
22+
}
23+
}
24+
}
25+
26+
[Test]
27+
public virtual void OneNewChildShouldOnlyCreateInsertWithNoUpdate_LockAndMerge()
28+
{
29+
var parentClone = _parent.MakeCopy();
30+
parentClone.AddChild(new Child());
31+
using (var s = OpenSession())
32+
{
33+
using (var tx = s.BeginTransaction())
34+
{
35+
s.Lock(_parent, LockMode.None);
36+
s.Merge(parentClone);
37+
s.SessionFactory.Statistics.Clear();
38+
tx.Commit();
39+
}
40+
41+
Assert.That(s.SessionFactory.Statistics.PrepareStatementCount, Is.EqualTo(1));
42+
}
43+
}
44+
45+
[Test]
46+
public virtual void OneNewChildShouldOnlyCreateInsertWithNoUpdate_Merge()
47+
{
48+
var parentClone = _parent.MakeCopy();
49+
parentClone.AddChild(new Child());
50+
using (var s = OpenSession())
51+
{
52+
using (var tx = s.BeginTransaction())
53+
{
54+
s.Merge(parentClone);
55+
s.SessionFactory.Statistics.Clear();
56+
tx.Commit();
57+
}
58+
59+
Assert.That(s.SessionFactory.Statistics.PrepareStatementCount, Is.EqualTo(1));
60+
}
61+
}
62+
63+
protected override void OnTearDown()
64+
{
65+
using (var s = OpenSession())
66+
{
67+
using (var tx = s.BeginTransaction())
68+
{
69+
s.Delete(s.Load<Parent>(_parent.Id));
70+
tx.Commit();
71+
}
72+
}
73+
}
74+
75+
protected override void Configure(Configuration configuration)
76+
{
77+
configuration.SetProperty(Environment.GenerateStatistics, "true");
78+
}
79+
}
80+
81+
[TestFixture]
82+
public class Fixture : FixtureBase
83+
{
84+
[Test]
85+
[KnownBug("#1530")]
86+
public override void OneNewChildShouldOnlyCreateInsertWithNoUpdate_Merge()
87+
{
88+
base.OneNewChildShouldOnlyCreateInsertWithNoUpdate_Merge();
89+
}
90+
91+
[Test]
92+
[KnownBug("#1530")]
93+
public override void OneNewChildShouldOnlyCreateInsertWithNoUpdate_LockAndMerge()
94+
{
95+
base.OneNewChildShouldOnlyCreateInsertWithNoUpdate_LockAndMerge();
96+
}
97+
}
98+
99+
[TestFixture]
100+
public class NonInverseFixture : FixtureBase
101+
{
102+
protected override string[] Mappings => new[] { "NonInverseMappings.hbm.xml" };
103+
}
104+
105+
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
<?xml version="1.0" encoding="utf-8" ?>
2+
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"
3+
namespace="NHibernate.Test.NHSpecificTest.GH1530"
4+
assembly="NHibernate.Test">
5+
<class name="Parent">
6+
<id name="Id" type="guid">
7+
<generator class="guid.comb"/>
8+
</id>
9+
<list name="Children" cascade="all-delete-orphan" inverse="true">
10+
<key column="Parent" not-null="true"/>
11+
<list-index column="OrderIndex"/>
12+
<one-to-many class="Child"/>
13+
</list>
14+
<property name="Name"/>
15+
</class>
16+
17+
<class name="Child">
18+
<id name="Id" type="guid">
19+
<generator class="guid.comb"/>
20+
</id>
21+
<many-to-one name="Parent" class="Parent"/>
22+
<property name="OrderIndex" access="readonly"/>
23+
<property name="Name"/>
24+
</class>
25+
</hibernate-mapping>
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
using System;
2+
using System.Collections.Generic;
3+
4+
namespace NHibernate.Test.NHSpecificTest.GH1530
5+
{
6+
public class Parent
7+
{
8+
public virtual Guid Id { get; set; }
9+
public virtual IList<Child> Children { get; set; } = new List<Child>();
10+
public virtual string Name { get; set; } = Guid.NewGuid().ToString();
11+
12+
public virtual void AddChild(Child child)
13+
{
14+
Children.Add(child);
15+
child.Parent = this;
16+
}
17+
18+
public virtual Parent MakeCopy()
19+
{
20+
var ret = new Parent { Id = Id, Name = Name };
21+
foreach (var child in Children)
22+
{
23+
ret.AddChild(new Child { Id = child.Id, Name = child.Name });
24+
}
25+
26+
return ret;
27+
}
28+
29+
public override bool Equals(object obj)
30+
{
31+
return obj is Parent other && Id == other.Id;
32+
}
33+
34+
public override int GetHashCode()
35+
{
36+
return 0;
37+
}
38+
}
39+
40+
public class Child
41+
{
42+
public virtual Guid Id { get; set; }
43+
public virtual string Name { get; set; } = Guid.NewGuid().ToString();
44+
public virtual Parent Parent { get; set; }
45+
46+
public virtual int OrderIndex
47+
{
48+
get
49+
{
50+
if (Parent == null)
51+
return -2;
52+
return Parent.Children.IndexOf(this);
53+
}
54+
}
55+
56+
public override bool Equals(object obj)
57+
{
58+
return obj is Child other && Id == other.Id;
59+
}
60+
61+
public override int GetHashCode()
62+
{
63+
return 0;
64+
}
65+
}
66+
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
<?xml version="1.0" encoding="utf-8" ?>
2+
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"
3+
namespace="NHibernate.Test.NHSpecificTest.GH1530"
4+
assembly="NHibernate.Test">
5+
<class name="Parent">
6+
<id name="Id" type="guid">
7+
<generator class="guid.comb"/>
8+
</id>
9+
<list name="Children" cascade="all-delete-orphan">
10+
<key column="Parent" not-null="true" update="false"/>
11+
<list-index column="OrderIndex"/>
12+
<one-to-many class="Child"/>
13+
</list>
14+
<property name="Name"/>
15+
</class>
16+
17+
18+
<class name="Child">
19+
<id name="Id" type="guid">
20+
<generator class="guid.comb"/>
21+
</id>
22+
<many-to-one name="Parent" class="Parent" update="false" insert="false"/>
23+
<property name="Name"/>
24+
</class>
25+
</hibernate-mapping>

0 commit comments

Comments
 (0)