diff --git a/src/NHibernate.Test/Async/NHSpecificTest/GH1628/Fixture.cs b/src/NHibernate.Test/Async/NHSpecificTest/GH1628/Fixture.cs new file mode 100644 index 00000000000..147257ed1cb --- /dev/null +++ b/src/NHibernate.Test/Async/NHSpecificTest/GH1628/Fixture.cs @@ -0,0 +1,72 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by AsyncGenerator. +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + + +using NUnit.Framework; + +namespace NHibernate.Test.NHSpecificTest.GH1628 +{ + using System.Threading.Tasks; + [TestFixture] + public class FixtureAsync : BugTestCase + { + protected override void OnSetUp() + { + using (var session = OpenSession()) + using (var transaction = session.BeginTransaction()) + { + var e1 = new Entity + { + Id = 1, + Name = "Bob", + ALongText = "Bob's very long text" + }; + session.Save(e1); + + var e2 = new Entity + { + Id = 2, + Name = "Sally", + ALongText = "Sally's very long text" + }; + session.Save(e2); + + transaction.Commit(); + } + } + + protected override void OnTearDown() + { + using (var session = OpenSession()) + using (var transaction = session.BeginTransaction()) + { + // The HQL delete does all the job inside the database without loading the entities, but it does + // not handle delete order for avoiding violating constraints if any. Use + // session.Delete("from System.Object"); + // instead if in need of having NHbernate ordering the deletes, but this will cause + // loading the entities in the session. + session.CreateQuery("delete from System.Object").ExecuteUpdate(); + + transaction.Commit(); + } + } + + [Test] + public async Task ShouldNotThrowStackOverflowExceptionAsync() + { + using (var session = OpenSession()) + using (session.BeginTransaction()) + { + IEntity result = await (session.GetAsync(2)); + Assert.That(result, Is.Not.Null); + Assert.That(result.Thing, Is.Null); + } + } + } +} diff --git a/src/NHibernate.Test/NHSpecificTest/GH1628/Entity.cs b/src/NHibernate.Test/NHSpecificTest/GH1628/Entity.cs new file mode 100644 index 00000000000..8dc238e8daa --- /dev/null +++ b/src/NHibernate.Test/NHSpecificTest/GH1628/Entity.cs @@ -0,0 +1,16 @@ +namespace NHibernate.Test.NHSpecificTest.GH1628 +{ +public interface IEntity +{ + object Thing { get; } +} + +public class Entity : IEntity +{ + public virtual int Id { get; set; } + + object IEntity.Thing { get { return null; } } + public virtual string Name { get; set; } + public virtual string ALongText { get; set; } +} +} diff --git a/src/NHibernate.Test/NHSpecificTest/GH1628/Fixture.cs b/src/NHibernate.Test/NHSpecificTest/GH1628/Fixture.cs new file mode 100644 index 00000000000..34ace2d9653 --- /dev/null +++ b/src/NHibernate.Test/NHSpecificTest/GH1628/Fixture.cs @@ -0,0 +1,61 @@ +using NUnit.Framework; + +namespace NHibernate.Test.NHSpecificTest.GH1628 +{ + [TestFixture] + public class Fixture : BugTestCase + { + protected override void OnSetUp() + { + using (var session = OpenSession()) + using (var transaction = session.BeginTransaction()) + { + var e1 = new Entity + { + Id = 1, + Name = "Bob", + ALongText = "Bob's very long text" + }; + session.Save(e1); + + var e2 = new Entity + { + Id = 2, + Name = "Sally", + ALongText = "Sally's very long text" + }; + session.Save(e2); + + transaction.Commit(); + } + } + + protected override void OnTearDown() + { + using (var session = OpenSession()) + using (var transaction = session.BeginTransaction()) + { + // The HQL delete does all the job inside the database without loading the entities, but it does + // not handle delete order for avoiding violating constraints if any. Use + // session.Delete("from System.Object"); + // instead if in need of having NHbernate ordering the deletes, but this will cause + // loading the entities in the session. + session.CreateQuery("delete from System.Object").ExecuteUpdate(); + + transaction.Commit(); + } + } + + [Test] + public void ShouldNotThrowStackOverflowException() + { + using (var session = OpenSession()) + using (session.BeginTransaction()) + { + IEntity result = session.Get(2); + Assert.That(result, Is.Not.Null); + Assert.That(result.Thing, Is.Null); + } + } + } +} diff --git a/src/NHibernate.Test/NHSpecificTest/GH1628/Mappings.hbm.xml b/src/NHibernate.Test/NHSpecificTest/GH1628/Mappings.hbm.xml new file mode 100644 index 00000000000..eee10a244f0 --- /dev/null +++ b/src/NHibernate.Test/NHSpecificTest/GH1628/Mappings.hbm.xml @@ -0,0 +1,11 @@ + + + + + + + + + + diff --git a/src/NHibernate/Proxy/DynamicProxy/ProxyFactory.cs b/src/NHibernate/Proxy/DynamicProxy/ProxyFactory.cs index 1865190f182..4df3f5bf588 100644 --- a/src/NHibernate/Proxy/DynamicProxy/ProxyFactory.cs +++ b/src/NHibernate/Proxy/DynamicProxy/ProxyFactory.cs @@ -98,8 +98,8 @@ private TypeInfo CreateUncachedProxyType(System.Type baseType, IReadOnlyCollecti { parentType = typeof (ProxyDummy); interfaces.Add(baseType); + interfaces.UnionWith(baseType.GetInterfaces()); } - interfaces.UnionWith(baseType.GetInterfaces()); // Add the ISerializable interface so that it can be implemented interfaces.Add(typeof (ISerializable));