Skip to content

Commit

Permalink
Use table group joins for many-to-many in Criteria and Entity loaders
Browse files Browse the repository at this point in the history
  • Loading branch information
bahusoid committed Mar 16, 2023
1 parent d419ab3 commit bc7e5c3
Show file tree
Hide file tree
Showing 18 changed files with 499 additions and 255 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ namespace NHibernate.Test.NHSpecificTest.GH1994
{
using System.Threading.Tasks;
[TestFixture]
public class FixtureAsync : BugTestCase
public class ManyToManyFilteredFixtureAsync : BugTestCase
{
protected override void OnSetUp()
{
Expand Down Expand Up @@ -150,5 +150,37 @@ public async Task TestQueryOverRestrictionWithClauseAsync()
Assert.That(query[0].Documents.Count, Is.EqualTo(1), "filtered asset documents");
}
}

[Test]
public async Task LazyLoadAsync()
{
if(Dialect is PostgreSQLDialect)
Assert.Ignore("Dialect doesn't support 0/1 to bool implicit cast");

using (var s = OpenSession())
{
var asset = await (s.Query<Asset>().FirstAsync());
Assert.That(asset.Documents.Count, Is.EqualTo(2));
Assert.That(asset.DocumentsBag.Count, Is.EqualTo(2));
Assert.That(asset.DocumentsFiltered.Count, Is.EqualTo(1));
}
}

[Test]
public async Task LazyLoadFilteredAsync()
{
if(Dialect is PostgreSQLDialect)
Assert.Ignore("Dialect doesn't support 0/1 to bool implicit cast");

using (var s = OpenSession())
{
s.EnableFilter("deletedFilter").SetParameter("deletedParam", false);

var asset = await (s.Query<Asset>().FirstAsync());
Assert.That(asset.Documents.Count, Is.EqualTo(1));
Assert.That(asset.DocumentsBag.Count, Is.EqualTo(1));
Assert.That(asset.DocumentsFiltered.Count, Is.EqualTo(1));
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,21 +10,55 @@

using System;
using NHibernate.Cfg;
using NHibernate.Criterion;
using NHibernate.Transform;
using NUnit.Framework;

namespace NHibernate.Test.NHSpecificTest.NH750
{
using System.Threading.Tasks;
[TestFixture]
public class FixtureAsync : BugTestCase
public class ManyToManyNotFoundIgnoreFixtureAsync : BugTestCase
{
private int id1;
private int id2;

protected override void OnSetUp()
{
Drive dr1 = new Drive("Drive 1");
Drive dr2 = new Drive("Drive 2");
Drive dr3 = new Drive("Drive 3");
Device dv1 = new Device("Device 1");
Device dv2 = new Device("Device 2");
using (var s = Sfi.OpenSession())
using (var t = s.BeginTransaction())
{
s.Save(dr1);
s.Save(dr2);
s.Save(dr3);
dv1.Drives.Add(dr1);
dv1.Drives.Add(dr2);
dv2.Drives.Add(dr1);
dv2.Drives.Add(dr3);

id1 = (int) s.Save(dv1);
id2 = (int) s.Save(dv2);
s.Flush();

s.Clear();
s.Delete(dr3);
t.Commit();
}
}

protected override void OnTearDown()
{
using (ISession s = Sfi.OpenSession())
using (var t = s.BeginTransaction())
{
s.Delete("from Device");
s.Delete("from Drive");
s.Flush();
t.Commit();
}
}

Expand All @@ -37,51 +71,17 @@ protected override void Configure(Configuration configuration)
[Test]
public async Task DeviceOfDriveAsync()
{
int[] dvSavedId = new int[2];
Drive dr1 = new Drive("Drive 1");
Drive dr2 = new Drive("Drive 2");
Drive dr3 = new Drive("Drive 3");
Device dv1 = new Device("Device 1");
Device dv2 = new Device("Device 2");
Device dv1;
Device dv2;
using (ISession s = Sfi.OpenSession())
{
await (s.SaveAsync(dr1));
await (s.SaveAsync(dr2));
await (s.SaveAsync(dr3));
dvSavedId[0] = (int) await (s.SaveAsync(dv1));
dvSavedId[1] = (int) await (s.SaveAsync(dv2));
await (s.FlushAsync());
dv1 = (Device) await (s.LoadAsync(typeof(Device), id1));
dv2 = (Device) await (s.LoadAsync(typeof(Device), id2));
}

dv1.Drives.Add(dr1);
dv1.Drives.Add(dr2);
dv2.Drives.Add(dr1);
dv2.Drives.Add(dr3);
using (ISession s = Sfi.OpenSession())
{
dvSavedId[0] = (int) await (s.SaveAsync(dv1));
dvSavedId[1] = (int) await (s.SaveAsync(dv2));
await (s.FlushAsync());
}
dv1 = null;
dv2 = null;
using (ISession s = Sfi.OpenSession())
{
await (s.DeleteAsync(dr3));
await (s.FlushAsync());
dv1 = (Device) await (s.LoadAsync(typeof(Device), dvSavedId[0]));
dv2 = (Device) await (s.LoadAsync(typeof(Device), dvSavedId[1]));
}
Assert.AreEqual(2, dv1.Drives.Count);
Assert.That(dv1.Drives, Has.Count.EqualTo(2).And.None.Null);
// Verify one is missing
Assert.AreEqual(1, dv2.Drives.Count);
// Verify dv1 unchanged
Assert.IsTrue(dv1.Drives.Contains(dr1));
Assert.IsTrue(dv1.Drives.Contains(dr2));

// Verify dv2
Assert.IsTrue(dv2.Drives.Contains(dr1));
Assert.IsFalse(dv2.Drives.Contains(dr3));
Assert.That(dv2.Drives, Has.Count.EqualTo(1).And.None.Null);

//Make sure that flush didn't touch not-found="ignore" records for not modified collection
using (var s = Sfi.OpenSession())
Expand All @@ -99,7 +99,7 @@ public async Task DeviceOfDriveAsync()
using (var t = s.BeginTransaction())
{
dv2 = await (s.GetAsync<Device>(dv2.Id));
dv2.Drives.Add(dr2);
dv2.Drives.Add(dv1.Drives[1]);
await (t.CommitAsync());
}

Expand All @@ -120,5 +120,49 @@ async Task VerifyResultAsync(int expectedInCollection, int expectedInDb, string
}
}
}

[Test]
public async Task QueryOverFetchAsync()
{
using (var s = OpenSession())
{
var dv2 = await (s.QueryOver<Device>()
.Fetch(SelectMode.Fetch, x => x.Drives)
.Where(Restrictions.IdEq(id2))
.TransformUsing(Transformers.DistinctRootEntity)
.SingleOrDefaultAsync());

Assert.That(NHibernateUtil.IsInitialized(dv2.Drives), Is.True);
Assert.That(dv2.Drives, Has.Count.EqualTo(1).And.None.Null);
}
}

[Test]
public async Task HqlFetchAsync()
{
using (var s = OpenSession())
{
var dv2 = await (s.CreateQuery("from Device d left join fetch d.Drives where d.id = :id")
.SetResultTransformer(Transformers.DistinctRootEntity)
.SetParameter("id", id2)
.UniqueResultAsync<Device>());

Assert.That(NHibernateUtil.IsInitialized(dv2.Drives), Is.True);
Assert.That(dv2.Drives, Has.Count.EqualTo(1).And.None.Null);
}
}

[Test]
public async Task LazyLoadAsync()
{
using (var s = OpenSession())
{
var dv2 = await (s.GetAsync<Device>(id2));
await (NHibernateUtil.InitializeAsync(dv2.Drives));

Assert.That(NHibernateUtil.IsInitialized(dv2.Drives), Is.True);
Assert.That(dv2.Drives, Has.Count.EqualTo(1).And.None.Null);
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,20 +8,22 @@
//------------------------------------------------------------------------------


using System.Linq;
using NHibernate.Criterion;
using NHibernate.Linq;
using NUnit.Framework;

namespace NHibernate.Test.PropertyRef
{
using System.Threading.Tasks;
[TestFixture]
[TestFixture(Description = "NH-2180 (GH-1214)")]
public class ManyToManyPropertyRefFixtureAsync : TestCase
{
protected override string[] Mappings => new[] { "PropertyRef.ManyToManyWithPropertyRef.hbm.xml" };

protected override string MappingsAssembly => "NHibernate.Test";

private object _manyAId;
private long _manyAId;

protected override void OnSetUp()
{
Expand All @@ -34,7 +36,7 @@ protected override void OnSetUp()
var manyB2 = new ManyB { Number = 8, Value = "a value of b2" };
var manyB3 = new ManyB { Number = 12, Value = "a value of b3" };

_manyAId = session.Save(manyA);
_manyAId = (long) session.Save(manyA);
session.Save(manyB1);
session.Save(manyB2);
session.Save(manyB3);
Expand Down Expand Up @@ -144,5 +146,20 @@ bei NHibernate.Type.EntityType.LoadByUniqueKey(String entityName, String uniqueK

Assert.That(loadedManyA.ManyBs, Has.Count.EqualTo(3).And.None.Null);
}

[Test]
public async Task LinqFetchAsync()
{
using (var session = OpenSession())
{
var manyA = (await (session
.Query<ManyA>()
.Where(a => a.Id == _manyAId)
.FetchMany(a => a.ManyBs)
.ToListAsync()))
.First();
Assert.That(manyA.ManyBs, Has.Count.EqualTo(3).And.None.Null);
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
namespace NHibernate.Test.NHSpecificTest.GH1994
{
[TestFixture]
public class Fixture : BugTestCase
public class ManyToManyFilteredFixture : BugTestCase
{
protected override void OnSetUp()
{
Expand Down Expand Up @@ -139,5 +139,37 @@ public void TestQueryOverRestrictionWithClause()
Assert.That(query[0].Documents.Count, Is.EqualTo(1), "filtered asset documents");
}
}

[Test]
public void LazyLoad()
{
if(Dialect is PostgreSQLDialect)
Assert.Ignore("Dialect doesn't support 0/1 to bool implicit cast");

using (var s = OpenSession())
{
var asset = s.Query<Asset>().First();
Assert.That(asset.Documents.Count, Is.EqualTo(2));
Assert.That(asset.DocumentsBag.Count, Is.EqualTo(2));
Assert.That(asset.DocumentsFiltered.Count, Is.EqualTo(1));
}
}

[Test]
public void LazyLoadFiltered()
{
if(Dialect is PostgreSQLDialect)
Assert.Ignore("Dialect doesn't support 0/1 to bool implicit cast");

using (var s = OpenSession())
{
s.EnableFilter("deletedFilter").SetParameter("deletedParam", false);

var asset = s.Query<Asset>().First();
Assert.That(asset.Documents.Count, Is.EqualTo(1));
Assert.That(asset.DocumentsBag.Count, Is.EqualTo(1));
Assert.That(asset.DocumentsFiltered.Count, Is.EqualTo(1));
}
}
}
}
9 changes: 8 additions & 1 deletion src/NHibernate.Test/NHSpecificTest/NH750/Device.cs
Original file line number Diff line number Diff line change
Expand Up @@ -33,11 +33,18 @@ public string Manifacturer
}

private IList<Drive> _drives = new List<Drive>();
private IList<Drive> _drivesNotIgnored = new List<Drive>();

public IList<Drive> Drives
{
get { return _drives; }
set { _drives = value; }
}

public IList<Drive> DrivesNotIgnored
{
get => _drivesNotIgnored;
set => _drivesNotIgnored = value;
}
}
}
}
Loading

0 comments on commit bc7e5c3

Please sign in to comment.