Skip to content

Commit af5e6fa

Browse files
Support mixed formulas and columns (#1808)
Many mapping elements allow to define their columns or formulas by nested elements, but most of them do not support having both nested columns and formulas. Follow-up to NH-2117, which has added this support to one-to-many. Throw on invalid usages of columns and formulas attributes and elements
1 parent f31fe59 commit af5e6fa

File tree

15 files changed

+935
-167
lines changed

15 files changed

+935
-167
lines changed

doc/reference/modules/example_mappings.xml

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -496,7 +496,6 @@ alter table line_items
496496

497497
</sect2>
498498

499-
<!-- This example is not supported by NHibernate, because HbmManyToMany lacks a ColumnsAndFormulas handling
500499
<sect2 id="example-mappings-miscellaneous-m2mcomposite">
501500
<title>Many-to-many with shared composite key attribute</title>
502501

@@ -535,8 +534,12 @@ alter table line_items
535534
</set>
536535
</class>]]></programlisting>
537536

537+
<para>
538+
This case requires mixing column and formula under the <literal>&lt;many-to-many&gt;</literal>
539+
element, which is supported only since NHibernate 5.2.
540+
</para>
541+
538542
</sect2>
539-
-->
540543

541544
<sect2 id="example-mappings-miscellaneous-contentdiscriminator">
542545
<title>Content based discrimination</title>
Lines changed: 221 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,221 @@
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 System;
12+
using System.Collections.Generic;
13+
using System.Linq;
14+
using NHibernate.Dialect;
15+
using NUnit.Framework;
16+
using NHibernate.Linq;
17+
18+
namespace NHibernate.Test.NHSpecificTest.GH1759
19+
{
20+
using System.Threading.Tasks;
21+
[TestFixture]
22+
public class ColumnsAndFormulasFixtureAsync : BugTestCase
23+
{
24+
// In fact most of the test happens at mapping compilation.
25+
protected override bool AppliesTo(Dialect.Dialect dialect)
26+
{
27+
// Uses some formulas with SLQ-Server transact SQL functions
28+
return dialect is MsSql2000Dialect;
29+
}
30+
31+
protected override void OnSetUp()
32+
{
33+
using (var session = OpenSession())
34+
using (var transaction = session.BeginTransaction())
35+
{
36+
var bob =
37+
new User
38+
{
39+
Name = "Bob",
40+
Org = "Eg",
41+
DepartureDate = DateTime.Parse("2012-07-01"),
42+
Hiring = new DateSpan
43+
{
44+
Date1 = DateTime.Parse("2001-01-01")
45+
}
46+
};
47+
session.Save(bob);
48+
49+
var sally =
50+
new User
51+
{
52+
Name = "Sally",
53+
Org = "Eg",
54+
Hiring = new DateSpan
55+
{
56+
Date1 = DateTime.Parse("2006-01-08")
57+
}
58+
};
59+
session.Save(sally);
60+
61+
var g1 = new Group { Name = "Salesperson", Org = "Eg" };
62+
g1.DateSpans.Add(new DateSpan { Date1 = DateTime.Parse("2000-12-31") });
63+
session.Save(g1);
64+
65+
var g2 = new Group { Name = "Manager", Org = "Eg" };
66+
session.Save(g2);
67+
68+
bob.Groups.Add(g1);
69+
g1.CommentsByUser.Add(bob, "He is gone, maybe he can be cleaned-up from the group.");
70+
sally.Groups.Add(g1);
71+
sally.Groups.Add(g2);
72+
73+
session.Flush();
74+
75+
// Needs to be done after the Flush, because this creates a circular reference.
76+
bob.MainGroupName = "Salesperson";
77+
sally.MainGroupName = "Salesperson";
78+
79+
transaction.Commit();
80+
}
81+
}
82+
83+
protected override void OnTearDown()
84+
{
85+
using (var session = OpenSession())
86+
using (var transaction = session.BeginTransaction())
87+
{
88+
// HQL "delete from" does neither handle the many-to-many table, nor the element table.
89+
// So using ISession.Delete instead of ISession.CreateQuery("delete...
90+
session.Delete("from User");
91+
session.Delete("from Group");
92+
93+
transaction.Commit();
94+
}
95+
}
96+
97+
[Test]
98+
public async Task CheckManyToManyAsync()
99+
{
100+
using (var session = OpenSession())
101+
using (var tx = session.BeginTransaction())
102+
{
103+
var bob = await (session.Query<User>().SingleAsync(u => u.Name == "Bob" && u.Org == "Eg"));
104+
var sally = await (session.Query<User>().SingleAsync(u => u.Name == "Sally" && u.Org == "Eg"));
105+
var salesperson = await (session.Query<Group>().SingleAsync(u => u.Name == "Salesperson" && u.Org == "Eg"));
106+
var manager = await (session.Query<Group>().SingleAsync(u => u.Name == "Manager" && u.Org == "Eg"));
107+
108+
Assert.That(
109+
bob.Groups,
110+
Has.Count.EqualTo(1)
111+
.And.One.EqualTo(salesperson));
112+
Assert.That(
113+
sally.Groups,
114+
Has.Count.EqualTo(2)
115+
.And.One.EqualTo(salesperson)
116+
.And.One.EqualTo(manager));
117+
Assert.That(
118+
salesperson.Users,
119+
Has.Count.EqualTo(2)
120+
.And.One.EqualTo(bob)
121+
.And.One.EqualTo(sally));
122+
Assert.That(
123+
manager.Users,
124+
Has.Count.EqualTo(1)
125+
.And.One.EqualTo(sally));
126+
127+
await (tx.CommitAsync());
128+
}
129+
}
130+
131+
[Test]
132+
public async Task CheckPropertyAsync()
133+
{
134+
using (var session = OpenSession())
135+
using (var tx = session.BeginTransaction())
136+
{
137+
var bob = await (session.Query<User>().SingleAsync(u => u.Name == "Bob" && u.Org == "Eg"));
138+
var sally = await (session.Query<User>().SingleAsync(u => u.Name == "Sally" && u.Org == "Eg"));
139+
140+
Assert.That(
141+
bob.Hiring,
142+
Has.Property(nameof(DateSpan.Date1)).EqualTo(DateTime.Parse("2001-01-01"))
143+
.And.Property(nameof(DateSpan.Date2)).EqualTo(bob.DepartureDate));
144+
Assert.That(
145+
sally.Hiring,
146+
Has.Property(nameof(DateSpan.Date1)).EqualTo(DateTime.Parse("2006-01-08"))
147+
.And.Property(nameof(DateSpan.Date2)).EqualTo(sally.DepartureDate));
148+
149+
sally.DepartureDate = DateTime.Today;
150+
151+
await (tx.CommitAsync());
152+
}
153+
154+
using (var session = OpenSession())
155+
using (var tx = session.BeginTransaction())
156+
{
157+
var sally = await (session.Query<User>().SingleAsync(u => u.Name == "Sally" && u.Org == "Eg"));
158+
Assert.That(sally.DepartureDate, Is.Not.Null);
159+
Assert.That(
160+
sally.Hiring,
161+
Has.Property(nameof(DateSpan.Date1)).EqualTo(DateTime.Parse("2006-01-08"))
162+
.And.Property(nameof(DateSpan.Date2)).EqualTo(sally.DepartureDate));
163+
164+
await (tx.CommitAsync());
165+
}
166+
}
167+
168+
[Test]
169+
public async Task CheckElementAsync()
170+
{
171+
using (var session = OpenSession())
172+
using (var tx = session.BeginTransaction())
173+
{
174+
var salesperson = await (session.Query<Group>().SingleAsync(u => u.Name == "Salesperson" && u.Org == "Eg"));
175+
176+
Assert.That(
177+
salesperson.DateSpans,
178+
Has.Count.GreaterThan(0)
179+
.And.All.Property(nameof(DateSpan.Date2)).EqualTo(DateTime.Parse("2000-12-31").AddYears(2)));
180+
181+
await (tx.CommitAsync());
182+
}
183+
}
184+
185+
[Test, Ignore("Needs an unrelated additional simple fix in OneToManyPersister")]
186+
public async Task CheckMapKeyAsync()
187+
{
188+
using (var session = OpenSession())
189+
using (var tx = session.BeginTransaction())
190+
{
191+
var salesperson = await (session.Query<Group>().SingleAsync(u => u.Name == "Salesperson" && u.Org == "Eg"));
192+
193+
Assert.That(
194+
salesperson.UsersByHiring,
195+
Has.Count.EqualTo(2)
196+
.And.One.Property(nameof(KeyValuePair<DateSpan, User>.Key)).Property(nameof(DateSpan.Date2)).Null
197+
.And.One.Property(nameof(KeyValuePair<DateSpan, User>.Key)).Property(nameof(DateSpan.Date2)).EqualTo(DateTime.Parse("2012-07-01")));
198+
199+
await (tx.CommitAsync());
200+
}
201+
}
202+
203+
[Test]
204+
public async Task CheckMapKeyManyToManyAsync()
205+
{
206+
using (var session = OpenSession())
207+
using (var tx = session.BeginTransaction())
208+
{
209+
var bob = await (session.Query<User>().SingleAsync(u => u.Name == "Bob" && u.Org == "Eg"));
210+
var salesperson = await (session.Query<Group>().SingleAsync(u => u.Name == "Salesperson" && u.Org == "Eg"));
211+
212+
Assert.That(
213+
salesperson.CommentsByUser,
214+
Has.Count.EqualTo(1)
215+
.And.One.Property(nameof(KeyValuePair<User, User>.Key)).EqualTo(bob).And.Property(nameof(KeyValuePair<User, User>.Value)).Length.GreaterThan(0));
216+
217+
await (tx.CommitAsync());
218+
}
219+
}
220+
}
221+
}

0 commit comments

Comments
 (0)