Skip to content

Commit

Permalink
Fix components list lazy loading with not lazy associations (#3321)
Browse files Browse the repository at this point in the history
Fixes #3317
  • Loading branch information
bahusoid authored Jun 17, 2023
1 parent 86d463a commit 8cb65c8
Show file tree
Hide file tree
Showing 4 changed files with 266 additions and 0 deletions.
123 changes: 123 additions & 0 deletions src/NHibernate.Test/Async/NHSpecificTest/GH3317/FixtureByCode.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
//------------------------------------------------------------------------------
// <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.Linq;
using NHibernate.Cfg.MappingSchema;
using NHibernate.Mapping.ByCode;
using NHibernate.Linq;
using NUnit.Framework;

namespace NHibernate.Test.NHSpecificTest.GH3317
{
using System.Threading.Tasks;
[TestFixture(true)]
[TestFixture(false)]
public class ComponentsListFixtureAsync : TestCaseMappingByCode
{
private readonly bool _fetchJoinMapping;
private Guid _id;

public ComponentsListFixtureAsync(bool fetchJoinMapping)
{
_fetchJoinMapping = fetchJoinMapping;
}

protected override void OnSetUp()
{
using var session = OpenSession();
using var tr = session.BeginTransaction();
var root = new Entity();
root.Entries.Add(new ComponentListEntry { ComponentReference = null, DummyString = "one", });

session.Save(root);
tr.Commit();
_id = root.Id;
}

[Test]
public async Task LazyLoadingAsync()
{
using var newSession = OpenSession();
var reloadedRoot = await (newSession.GetAsync<Entity>(_id));
Assert.AreEqual(1, reloadedRoot.Entries.Count);
}

[Test]
public async Task QueryOverFetchAsync()
{
using var newSession = OpenSession();
var reloadedRoot = await (newSession.QueryOver<Entity>()
.Fetch(SelectMode.Fetch, x => x.Entries)
.Where(x => x.Id == _id)
.SingleOrDefaultAsync());
Assert.AreEqual(1, reloadedRoot.Entries.Count);
}

[Test]
public async Task LinqFetchAsync()
{
using var newSession = OpenSession();
var reloadedRoot = await (newSession.Query<Entity>()
.Fetch(x => x.Entries)
.Where(x => x.Id == _id)
.SingleOrDefaultAsync());
Assert.AreEqual(1, reloadedRoot.Entries.Count);
}

protected override void OnTearDown()
{
using var session = OpenSession();
using var transaction = session.BeginTransaction();
session.CreateSQLQuery("delete from Entries").ExecuteUpdate();
session.Delete("from System.Object");
transaction.Commit();
}

protected override HbmMapping GetMappings()
{
var mapper = new ModelMapper();

mapper.Class<Entity>(rc =>
{
rc.Id(x => x.Id, map => map.Generator(Generators.GuidComb));
rc.Lazy(false);
rc.Property(x => x.Name);
rc.Bag(
x => x.Entries,
v =>
{
if (_fetchJoinMapping)
v.Fetch(CollectionFetchMode.Join);
},
h => h.Component(cmp =>
{
cmp.Property(x => x.DummyString);
cmp.ManyToOne(x => x.ComponentReference);
}));
});
mapper.Class<EntityWithParent>(rc =>
{
rc.Id(x => x.Id, map => map.Generator(Generators.GuidComb));
rc.Lazy(false);
rc.ManyToOne(x => x.Parent, m => m.NotNullable(true));
});
mapper.Class<ParentEntity>(rc =>
{
rc.Id(x => x.Id, map => map.Generator(Generators.GuidComb));
rc.Lazy(false);
rc.Property(x => x.Name);
});

return mapper.CompileMappingForAllExplicitlyAddedEntities();
}
}
}
30 changes: 30 additions & 0 deletions src/NHibernate.Test/NHSpecificTest/GH3317/Entity.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
using System;
using System.Collections.Generic;

namespace NHibernate.Test.NHSpecificTest.GH3317
{
public class Entity
{
public Guid Id { get; set; }
public string Name { get; set; }
public IList<ComponentListEntry> Entries { get; set; } = new List<ComponentListEntry>();
}

public class ComponentListEntry
{
public string DummyString { get; set; }
public EntityWithParent ComponentReference { get; set; }
}

public class EntityWithParent
{
public Guid Id { get; set; }
public ParentEntity Parent { get; set; }
}

public class ParentEntity
{
public Guid Id { get; set; }
public string Name { get; set; }
}
}
112 changes: 112 additions & 0 deletions src/NHibernate.Test/NHSpecificTest/GH3317/FixtureByCode.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
using System;
using System.Linq;
using NHibernate.Cfg.MappingSchema;
using NHibernate.Mapping.ByCode;
using NHibernate.Linq;
using NUnit.Framework;

namespace NHibernate.Test.NHSpecificTest.GH3317
{
[TestFixture(true)]
[TestFixture(false)]
public class ComponentsListFixture : TestCaseMappingByCode
{
private readonly bool _fetchJoinMapping;
private Guid _id;

public ComponentsListFixture(bool fetchJoinMapping)
{
_fetchJoinMapping = fetchJoinMapping;
}

protected override void OnSetUp()
{
using var session = OpenSession();
using var tr = session.BeginTransaction();
var root = new Entity();
root.Entries.Add(new ComponentListEntry { ComponentReference = null, DummyString = "one", });

session.Save(root);
tr.Commit();
_id = root.Id;
}

[Test]
public void LazyLoading()
{
using var newSession = OpenSession();
var reloadedRoot = newSession.Get<Entity>(_id);
Assert.AreEqual(1, reloadedRoot.Entries.Count);
}

[Test]
public void QueryOverFetch()
{
using var newSession = OpenSession();
var reloadedRoot = newSession.QueryOver<Entity>()
.Fetch(SelectMode.Fetch, x => x.Entries)
.Where(x => x.Id == _id)
.SingleOrDefault();
Assert.AreEqual(1, reloadedRoot.Entries.Count);
}

[Test]
public void LinqFetch()
{
using var newSession = OpenSession();
var reloadedRoot = newSession.Query<Entity>()
.Fetch(x => x.Entries)
.Where(x => x.Id == _id)
.SingleOrDefault();
Assert.AreEqual(1, reloadedRoot.Entries.Count);
}

protected override void OnTearDown()
{
using var session = OpenSession();
using var transaction = session.BeginTransaction();
session.CreateSQLQuery("delete from Entries").ExecuteUpdate();
session.Delete("from System.Object");
transaction.Commit();
}

protected override HbmMapping GetMappings()
{
var mapper = new ModelMapper();

mapper.Class<Entity>(rc =>
{
rc.Id(x => x.Id, map => map.Generator(Generators.GuidComb));
rc.Lazy(false);
rc.Property(x => x.Name);
rc.Bag(
x => x.Entries,
v =>
{
if (_fetchJoinMapping)
v.Fetch(CollectionFetchMode.Join);
},
h => h.Component(cmp =>
{
cmp.Property(x => x.DummyString);
cmp.ManyToOne(x => x.ComponentReference);
}));
});
mapper.Class<EntityWithParent>(rc =>
{
rc.Id(x => x.Id, map => map.Generator(Generators.GuidComb));
rc.Lazy(false);
rc.ManyToOne(x => x.Parent, m => m.NotNullable(true));
});
mapper.Class<ParentEntity>(rc =>
{
rc.Id(x => x.Id, map => map.Generator(Generators.GuidComb));
rc.Lazy(false);
rc.Property(x => x.Name);
});

return mapper.CompileMappingForAllExplicitlyAddedEntities();
}
}
}
1 change: 1 addition & 0 deletions src/NHibernate/Loader/JoinWalker.cs
Original file line number Diff line number Diff line change
Expand Up @@ -375,6 +375,7 @@ private void WalkCollectionTree(IQueryableCollection persister, string alias, st
}
else if (type.IsComponentType)
{
_joinQueue.Enqueue(NextLevelJoinQueueEntry.Instance);
WalkCompositeElementTree(
(IAbstractComponentType) type,
persister.ElementColumnNames,
Expand Down

0 comments on commit 8cb65c8

Please sign in to comment.