Skip to content

Commit c2ff067

Browse files
bahusoidhazzik
authored andcommitted
Test ISession.IsDurty() does not trigger cascade saving with native generator
Depending on the db, an insert may be triggered (SQL-Server) or not (Oracle). Tested with Statistics rather than SqlLogSpy: it avoids parsing the SQL for distinguishing between select (done with Oracle over the sequence) and insert (done with SQL-Server). See nhibernate#1413
1 parent 1b0efb7 commit c2ff067

File tree

3 files changed

+228
-0
lines changed

3 files changed

+228
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
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.MappingSchema;
12+
using NHibernate.Mapping.ByCode;
13+
using NUnit.Framework;
14+
15+
namespace NHibernate.Test.NHSpecificTest.GH1413
16+
{
17+
using System.Threading.Tasks;
18+
using System.Threading;
19+
[TestFixture]
20+
public class ByCodeFixtureAsync : TestCaseMappingByCode
21+
{
22+
private int _parentId;
23+
24+
protected override HbmMapping GetMappings()
25+
{
26+
var mapper = new ModelMapper();
27+
mapper.Class<EntityParent>(rc =>
28+
{
29+
rc.Id(x => x.Id, m => m.Generator(Generators.Native));
30+
rc.Property(x => x.Name);
31+
rc.Bag(x => x.Children, m =>
32+
{
33+
m.Cascade(Mapping.ByCode.Cascade.All);
34+
m.Inverse(true);
35+
}, a => a.OneToMany()
36+
);
37+
});
38+
39+
mapper.Class<EntityChild>(rc =>
40+
{
41+
rc.Id(x => x.Id, m => m.Generator(Generators.Native));
42+
rc.Property(x => x.Name);
43+
});
44+
45+
return mapper.CompileMappingForAllExplicitlyAddedEntities();
46+
}
47+
48+
protected override void OnSetUp()
49+
{
50+
using (var session = OpenSession())
51+
using (var transaction = session.BeginTransaction())
52+
{
53+
var parent = new EntityParent
54+
{
55+
Name = "InitialParent",
56+
};
57+
session.Save(parent);
58+
59+
session.Flush();
60+
transaction.Commit();
61+
_parentId = parent.Id;
62+
}
63+
}
64+
65+
protected override void OnTearDown()
66+
{
67+
using (var session = OpenSession())
68+
using (var transaction = session.BeginTransaction())
69+
{
70+
session.Delete("from System.Object");
71+
72+
session.Flush();
73+
transaction.Commit();
74+
}
75+
}
76+
77+
[Test]
78+
[KnownBug("#1413")]
79+
public async Task SessionIsDirtyShouldNotTriggerCascadeSavingAsync()
80+
{
81+
Sfi.Statistics.IsStatisticsEnabled = true;
82+
using (var session = OpenSession())
83+
using (session.BeginTransaction())
84+
{
85+
var parent = await (GetParentAsync(session));
86+
var entityChild = new EntityChild
87+
{
88+
Name = "NewListElem"
89+
};
90+
91+
//parent.Children is cascaded
92+
parent.Children.Add(entityChild);
93+
94+
Sfi.Statistics.Clear();
95+
var isDirty = await (session.IsDirtyAsync());
96+
97+
Assert.That(Sfi.Statistics.EntityInsertCount, Is.EqualTo(0), "Dirty has triggered an insert");
98+
Assert.That(
99+
entityChild.Id,
100+
Is.EqualTo(0),
101+
"Transient objects should not be saved by ISession.IsDirty() call (expected 0 as Id)");
102+
Assert.That(isDirty, "ISession.IsDirty() call should return true.");
103+
}
104+
}
105+
106+
private Task<EntityParent> GetParentAsync(ISession session, CancellationToken cancellationToken = default(CancellationToken))
107+
{
108+
return session.GetAsync<EntityParent>(_parentId, cancellationToken);
109+
}
110+
}
111+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
using System;
2+
using System.Collections.Generic;
3+
4+
namespace NHibernate.Test.NHSpecificTest.GH1413
5+
{
6+
public class EntityChild
7+
{
8+
public virtual int Id { get; set; }
9+
public virtual string Name { get; set; }
10+
}
11+
12+
public class EntityParent
13+
{
14+
public virtual int Id { get; set; }
15+
public virtual string Name { get; set; }
16+
public virtual IList<EntityChild> Children { get; set; } = new List<EntityChild>();
17+
}
18+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
using NHibernate.Cfg.MappingSchema;
2+
using NHibernate.Mapping.ByCode;
3+
using NUnit.Framework;
4+
5+
namespace NHibernate.Test.NHSpecificTest.GH1413
6+
{
7+
[TestFixture]
8+
public class ByCodeFixture : TestCaseMappingByCode
9+
{
10+
private int _parentId;
11+
12+
protected override HbmMapping GetMappings()
13+
{
14+
var mapper = new ModelMapper();
15+
mapper.Class<EntityParent>(rc =>
16+
{
17+
rc.Id(x => x.Id, m => m.Generator(Generators.Native));
18+
rc.Property(x => x.Name);
19+
rc.Bag(x => x.Children, m =>
20+
{
21+
m.Cascade(Mapping.ByCode.Cascade.All);
22+
m.Inverse(true);
23+
}, a => a.OneToMany()
24+
);
25+
});
26+
27+
mapper.Class<EntityChild>(rc =>
28+
{
29+
rc.Id(x => x.Id, m => m.Generator(Generators.Native));
30+
rc.Property(x => x.Name);
31+
});
32+
33+
return mapper.CompileMappingForAllExplicitlyAddedEntities();
34+
}
35+
36+
protected override void OnSetUp()
37+
{
38+
using (var session = OpenSession())
39+
using (var transaction = session.BeginTransaction())
40+
{
41+
var parent = new EntityParent
42+
{
43+
Name = "InitialParent",
44+
};
45+
session.Save(parent);
46+
47+
session.Flush();
48+
transaction.Commit();
49+
_parentId = parent.Id;
50+
}
51+
}
52+
53+
protected override void OnTearDown()
54+
{
55+
using (var session = OpenSession())
56+
using (var transaction = session.BeginTransaction())
57+
{
58+
session.Delete("from System.Object");
59+
60+
session.Flush();
61+
transaction.Commit();
62+
}
63+
}
64+
65+
[Test]
66+
[KnownBug("#1413")]
67+
public void SessionIsDirtyShouldNotTriggerCascadeSaving()
68+
{
69+
Sfi.Statistics.IsStatisticsEnabled = true;
70+
using (var session = OpenSession())
71+
using (session.BeginTransaction())
72+
{
73+
var parent = GetParent(session);
74+
var entityChild = new EntityChild
75+
{
76+
Name = "NewListElem"
77+
};
78+
79+
//parent.Children is cascaded
80+
parent.Children.Add(entityChild);
81+
82+
Sfi.Statistics.Clear();
83+
var isDirty = session.IsDirty();
84+
85+
Assert.That(Sfi.Statistics.EntityInsertCount, Is.EqualTo(0), "Dirty has triggered an insert");
86+
Assert.That(
87+
entityChild.Id,
88+
Is.EqualTo(0),
89+
"Transient objects should not be saved by ISession.IsDirty() call (expected 0 as Id)");
90+
Assert.That(isDirty, "ISession.IsDirty() call should return true.");
91+
}
92+
}
93+
94+
private EntityParent GetParent(ISession session)
95+
{
96+
return session.Get<EntityParent>(_parentId);
97+
}
98+
}
99+
}

0 commit comments

Comments
 (0)