Skip to content

Support formula on one-to-many map-key #1760

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
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
//------------------------------------------------------------------------------
// <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 NUnit.Framework;
using NHibernate.Linq;

namespace NHibernate.Test.NHSpecificTest.GH1760
{
using System.Threading.Tasks;
[TestFixture]
public class MapKeyFormulasFixtureAsync : BugTestCase
{
protected override void OnSetUp()
{
using (var session = OpenSession())
using (var transaction = session.BeginTransaction())
{
var bob =
new User
{
Name = "Bob"
};
session.Save(bob);

var sally =
new User
{
Name = "Sally"
};
session.Save(sally);

var g1 = new Group { Name = "Salesperson" };
session.Save(g1);

g1.UsersByName.Add(bob.Name, bob);
g1.UsersByName.Add(sally.Name, sally);

transaction.Commit();
}
}

protected override void OnTearDown()
{
using (var session = OpenSession())
using (var transaction = session.BeginTransaction())
{
// HQL "delete from" does not handle foreign key order.
session.Delete("from User");
session.CreateQuery("delete System.Object").ExecuteUpdate();

transaction.Commit();
}
}

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

Assert.That(
salesperson.UsersByName,
Has.Count.EqualTo(2)
.And.One.Property(nameof(KeyValuePair<string, User>.Key)).EqualTo("Bob")
.And.One.Property(nameof(KeyValuePair<string, User>.Key)).EqualTo("Sally"));

await (tx.CommitAsync());
}
}
}
}
19 changes: 19 additions & 0 deletions src/NHibernate.Test/NHSpecificTest/GH1760/Domain.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
using System;
using System.Collections.Generic;

namespace NHibernate.Test.NHSpecificTest.GH1760
{
class User
{
public virtual Guid Id { get; set; }
public virtual string Name { get; set; }
}

class Group
{
public virtual Guid Id { get; set; }
public virtual string Name { get; set; }

public virtual IDictionary<string, User> UsersByName { get; set; } = new Dictionary<string, User>();
}
}
71 changes: 71 additions & 0 deletions src/NHibernate.Test/NHSpecificTest/GH1760/MapKeyFormulaFixture.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
using System;
using System.Collections.Generic;
using System.Linq;
using NUnit.Framework;

namespace NHibernate.Test.NHSpecificTest.GH1760
{
[TestFixture]
public class MapKeyFormulasFixture : BugTestCase
{
protected override void OnSetUp()
{
using (var session = OpenSession())
using (var transaction = session.BeginTransaction())
{
var bob =
new User
{
Name = "Bob"
};
session.Save(bob);

var sally =
new User
{
Name = "Sally"
};
session.Save(sally);

var g1 = new Group { Name = "Salesperson" };
session.Save(g1);

g1.UsersByName.Add(bob.Name, bob);
g1.UsersByName.Add(sally.Name, sally);

transaction.Commit();
}
}

protected override void OnTearDown()
{
using (var session = OpenSession())
using (var transaction = session.BeginTransaction())
{
// HQL "delete from" does not handle foreign key order.
session.Delete("from User");
session.CreateQuery("delete System.Object").ExecuteUpdate();

transaction.Commit();
}
}

[Test]
public void CheckMapKey()
{
using (var session = OpenSession())
using (var tx = session.BeginTransaction())
{
var salesperson = session.Query<Group>().Single(u => u.Name == "Salesperson");

Assert.That(
salesperson.UsersByName,
Has.Count.EqualTo(2)
.And.One.Property(nameof(KeyValuePair<string, User>.Key)).EqualTo("Bob")
.And.One.Property(nameof(KeyValuePair<string, User>.Key)).EqualTo("Sally"));

tx.Commit();
}
}
}
}
24 changes: 24 additions & 0 deletions src/NHibernate.Test/NHSpecificTest/GH1760/Mappings.hbm.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" assembly="NHibernate.Test"
namespace="NHibernate.Test.NHSpecificTest.GH1760">

<class name="User" table="`User`">
<id name="Id" generator="guid.comb"/>
<property name="Name"/>
</class>

<class name="Group" table="`Group`">
<id name="Id" generator="guid.comb"/>

<property name="Name"/>

<map name="UsersByName">
<key column="GroupId"/>
<map-key type="string">
<formula>Name</formula>
</map-key>
<one-to-many class="User"/>
</map>
</class>

</hibernate-mapping>
2 changes: 1 addition & 1 deletion src/NHibernate/Persister/Collection/OneToManyPersister.cs
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ protected override SqlCommandInfo GenerateDeleteString()
update.SetJoin(ownerPersister.TableName, KeyColumnNames, KeyType, JoinColumnNames, ownerPersister.GetPropertyColumnNames(CollectionType.LHSPropertyName));
}

if (HasIndex)
if (HasIndex && !indexContainsFormula)
Copy link
Member Author

@fredericDelaporte fredericDelaporte Jun 19, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is from GenerateDeleteRowString own logic. It seems the GenerateDeleteString case was just forgotten.
By the way nullifying the index columns makes surely sense for an one-to-many list mapping, but for an one-to-many map mapping, this looks as a bad thing to me...
Anyway with this PR we will have a workaround if the nullifying of a map-key causes troubles: mapping it as a formula instead.

This comment was marked as off-topic.

This comment was marked as off-topic.

update.AddColumns(IndexColumnNames, "null");

if (HasWhere)
Expand Down