Skip to content

Fix components list lazy loading with not lazy associations #3321

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 3 commits into from
Jun 17, 2023
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
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