Skip to content

Issue with components list lazy loading with not lazy association #3317

@bahusoid

Description

@bahusoid

Originally posted by @BhaaLseN in #3290 (comment):

We see this issue on Bags that contain Components which then refer to other mapped entities. The curious thing is that it fails to re-insert the new entries because the old ones aren't deleted properly (DB says no due to PK violations), but this only happens when one of references is set but the other is null. So it is only half broken for us.

public class RootEntity
{
	public Guid Id { 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 class Test3290 : TestCaseMappingByCode
{
	[Test]
	public void ThisFails()
	{
		RootEntity root;
		using (var session = OpenSession())
		{
			root = new RootEntity();
			root.Entries.Add(new ComponentListEntry
			{
				// loading (and also subsequent updates) fail when this is null
				ComponentReference = null,
				DummyString = "one",
			});

			session.Save(root);
			session.Flush();
		}

		using var newSession = OpenSession();
		var reloadedRoot = newSession.Get<RootEntity>(root.Id);
		Assert.AreEqual(1, reloadedRoot.Entries.Count);
	}

	[Test]
	public void ThisWorks()
	{
		RootEntity root;
		using (var session = OpenSession())
		{
			var parent = new ParentEntity();
			session.Save(parent);
			var entityWithParent = new EntityWithParent { Parent = parent };
			session.Save(entityWithParent);

			root = new RootEntity();
			root.Entries.Add(new ComponentListEntry
			{
				// loading (and also subsequent updates) work when this is set
				ComponentReference = entityWithParent,
				DummyString = "one",
			});

			session.Save(root);
			session.Flush();
		}

		using var newSession = OpenSession();
		var reloadedRoot = newSession.Get<RootEntity>(root.Id);
		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<RootEntity>(rc =>
		{
			rc.Id(x => x.Id, map => map.Generator(Generators.GuidComb));
			rc.Lazy(false);

			rc.Bag(
				x => x.Entries,
				v =>
				{
					v.Access(Accessor.Property);
					v.Lazy(CollectionLazy.NoLazy);
					v.Fetch(CollectionFetchMode.Select);
				},
				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);
		});

		return mapper.CompileMappingForAllExplicitlyAddedEntities();
	}
}

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions