Skip to content

Support mixed formulas and columns #1808

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 5 additions & 2 deletions doc/reference/modules/example_mappings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -496,7 +496,6 @@ alter table line_items

</sect2>

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

Expand Down Expand Up @@ -535,8 +534,12 @@ alter table line_items
</set>
</class>]]></programlisting>

<para>
This case requires mixing column and formula under the <literal>&lt;many-to-many&gt;</literal>
element, which is supported only since NHibernate 5.2.
</para>

</sect2>
-->

<sect2 id="example-mappings-miscellaneous-contentdiscriminator">
<title>Content based discrimination</title>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,221 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by AsyncGenerator.
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------


using System;
using System.Collections.Generic;
using System.Linq;
using NHibernate.Dialect;
using NUnit.Framework;
using NHibernate.Linq;

namespace NHibernate.Test.NHSpecificTest.GH1759
{
using System.Threading.Tasks;
[TestFixture]
public class ColumnsAndFormulasFixtureAsync : BugTestCase
{
// In fact most of the test happens at mapping compilation.
protected override bool AppliesTo(Dialect.Dialect dialect)
{
// Uses some formulas with SLQ-Server transact SQL functions
return dialect is MsSql2000Dialect;
}

protected override void OnSetUp()
{
using (var session = OpenSession())
using (var transaction = session.BeginTransaction())
{
var bob =
new User
{
Name = "Bob",
Org = "Eg",
DepartureDate = DateTime.Parse("2012-07-01"),
Hiring = new DateSpan
{
Date1 = DateTime.Parse("2001-01-01")
}
};
session.Save(bob);

var sally =
new User
{
Name = "Sally",
Org = "Eg",
Hiring = new DateSpan
{
Date1 = DateTime.Parse("2006-01-08")
}
};
session.Save(sally);

var g1 = new Group { Name = "Salesperson", Org = "Eg" };
g1.DateSpans.Add(new DateSpan { Date1 = DateTime.Parse("2000-12-31") });
session.Save(g1);

var g2 = new Group { Name = "Manager", Org = "Eg" };
session.Save(g2);

bob.Groups.Add(g1);
g1.CommentsByUser.Add(bob, "He is gone, maybe he can be cleaned-up from the group.");
sally.Groups.Add(g1);
sally.Groups.Add(g2);

session.Flush();

// Needs to be done after the Flush, because this creates a circular reference.
bob.MainGroupName = "Salesperson";
sally.MainGroupName = "Salesperson";

transaction.Commit();
}
}

protected override void OnTearDown()
{
using (var session = OpenSession())
using (var transaction = session.BeginTransaction())
{
// HQL "delete from" does neither handle the many-to-many table, nor the element table.
// So using ISession.Delete instead of ISession.CreateQuery("delete...
session.Delete("from User");
session.Delete("from Group");

transaction.Commit();
}
}

[Test]
public async Task CheckManyToManyAsync()
{
using (var session = OpenSession())
using (var tx = session.BeginTransaction())
{
var bob = await (session.Query<User>().SingleAsync(u => u.Name == "Bob" && u.Org == "Eg"));
var sally = await (session.Query<User>().SingleAsync(u => u.Name == "Sally" && u.Org == "Eg"));
var salesperson = await (session.Query<Group>().SingleAsync(u => u.Name == "Salesperson" && u.Org == "Eg"));
var manager = await (session.Query<Group>().SingleAsync(u => u.Name == "Manager" && u.Org == "Eg"));

Assert.That(
bob.Groups,
Has.Count.EqualTo(1)
.And.One.EqualTo(salesperson));
Assert.That(
sally.Groups,
Has.Count.EqualTo(2)
.And.One.EqualTo(salesperson)
.And.One.EqualTo(manager));
Assert.That(
salesperson.Users,
Has.Count.EqualTo(2)
.And.One.EqualTo(bob)
.And.One.EqualTo(sally));
Assert.That(
manager.Users,
Has.Count.EqualTo(1)
.And.One.EqualTo(sally));

await (tx.CommitAsync());
}
}

[Test]
public async Task CheckPropertyAsync()
{
using (var session = OpenSession())
using (var tx = session.BeginTransaction())
{
var bob = await (session.Query<User>().SingleAsync(u => u.Name == "Bob" && u.Org == "Eg"));
var sally = await (session.Query<User>().SingleAsync(u => u.Name == "Sally" && u.Org == "Eg"));

Assert.That(
bob.Hiring,
Has.Property(nameof(DateSpan.Date1)).EqualTo(DateTime.Parse("2001-01-01"))
.And.Property(nameof(DateSpan.Date2)).EqualTo(bob.DepartureDate));
Assert.That(
sally.Hiring,
Has.Property(nameof(DateSpan.Date1)).EqualTo(DateTime.Parse("2006-01-08"))
.And.Property(nameof(DateSpan.Date2)).EqualTo(sally.DepartureDate));

sally.DepartureDate = DateTime.Today;

await (tx.CommitAsync());
}

using (var session = OpenSession())
using (var tx = session.BeginTransaction())
{
var sally = await (session.Query<User>().SingleAsync(u => u.Name == "Sally" && u.Org == "Eg"));
Assert.That(sally.DepartureDate, Is.Not.Null);
Assert.That(
sally.Hiring,
Has.Property(nameof(DateSpan.Date1)).EqualTo(DateTime.Parse("2006-01-08"))
.And.Property(nameof(DateSpan.Date2)).EqualTo(sally.DepartureDate));

await (tx.CommitAsync());
}
}

[Test]
public async Task CheckElementAsync()
{
using (var session = OpenSession())
using (var tx = session.BeginTransaction())
{
var salesperson = await (session.Query<Group>().SingleAsync(u => u.Name == "Salesperson" && u.Org == "Eg"));

Assert.That(
salesperson.DateSpans,
Has.Count.GreaterThan(0)
.And.All.Property(nameof(DateSpan.Date2)).EqualTo(DateTime.Parse("2000-12-31").AddYears(2)));

await (tx.CommitAsync());
}
}

[Test, Ignore("Needs an unrelated additional simple fix in OneToManyPersister")]
public async Task CheckMapKeyAsync()
{
using (var session = OpenSession())
using (var tx = session.BeginTransaction())
{
var salesperson = await (session.Query<Group>().SingleAsync(u => u.Name == "Salesperson" && u.Org == "Eg"));

Assert.That(
salesperson.UsersByHiring,
Has.Count.EqualTo(2)
.And.One.Property(nameof(KeyValuePair<DateSpan, User>.Key)).Property(nameof(DateSpan.Date2)).Null
.And.One.Property(nameof(KeyValuePair<DateSpan, User>.Key)).Property(nameof(DateSpan.Date2)).EqualTo(DateTime.Parse("2012-07-01")));

await (tx.CommitAsync());
}
}

[Test]
public async Task CheckMapKeyManyToManyAsync()
{
using (var session = OpenSession())
using (var tx = session.BeginTransaction())
{
var bob = await (session.Query<User>().SingleAsync(u => u.Name == "Bob" && u.Org == "Eg"));
var salesperson = await (session.Query<Group>().SingleAsync(u => u.Name == "Salesperson" && u.Org == "Eg"));

Assert.That(
salesperson.CommentsByUser,
Has.Count.EqualTo(1)
.And.One.Property(nameof(KeyValuePair<User, User>.Key)).EqualTo(bob).And.Property(nameof(KeyValuePair<User, User>.Value)).Length.GreaterThan(0));

await (tx.CommitAsync());
}
}
}
}
Loading