From 3ab267c5e6b5a32fe0acb53dd16c53502c81f934 Mon Sep 17 00:00:00 2001 From: Alexander Zaytsev Date: Tue, 19 Mar 2019 16:38:08 +1300 Subject: [PATCH 1/8] Fix base type for interface proxies --- .../NHSpecificTest/GH2067/Domain.cs | 30 ++++ .../NHSpecificTest/GH2067/Fixture.cs | 143 ++++++++++++++++++ src/NHibernate/Proxy/StaticProxyFactory.cs | 16 +- 3 files changed, 188 insertions(+), 1 deletion(-) create mode 100644 src/NHibernate.Test/NHSpecificTest/GH2067/Domain.cs create mode 100644 src/NHibernate.Test/NHSpecificTest/GH2067/Fixture.cs diff --git a/src/NHibernate.Test/NHSpecificTest/GH2067/Domain.cs b/src/NHibernate.Test/NHSpecificTest/GH2067/Domain.cs new file mode 100644 index 00000000000..1481b3b5b76 --- /dev/null +++ b/src/NHibernate.Test/NHSpecificTest/GH2067/Domain.cs @@ -0,0 +1,30 @@ +using System; + +namespace NHibernate.Test.NHSpecificTest.GH2067 +{ + public interface ICat + { + Guid Id { get; set; } + string Name { get; set; } + } + + public class Cat : ICat + { + public virtual Guid Id { get; set; } + public virtual string Name { get; set; } + } + + public interface IPet + { + string OwnerName { get; set; } + } + + public interface IDomesticCat : IPet, ICat + { + } + + public sealed class DomesticCat : Cat, IDomesticCat + { + public string OwnerName { get; set; } + } +} diff --git a/src/NHibernate.Test/NHSpecificTest/GH2067/Fixture.cs b/src/NHibernate.Test/NHSpecificTest/GH2067/Fixture.cs new file mode 100644 index 00000000000..3f72e36f270 --- /dev/null +++ b/src/NHibernate.Test/NHSpecificTest/GH2067/Fixture.cs @@ -0,0 +1,143 @@ +using System; +using NHibernate.Cfg.MappingSchema; +using NHibernate.Mapping.ByCode; +using NUnit.Framework; + +namespace NHibernate.Test.NHSpecificTest.GH2067 +{ + [TestFixture] + public class Fixture : TestCaseMappingByCode + { + private object domesticCatId; + private object catId; + + protected override HbmMapping GetMappings() + { + var mapper = new ModelMapper(); + mapper.Class(rc => + { + rc.Id(x => x.Id, m => m.Generator(Generators.GuidComb)); + rc.Property(x => x.Name); + }); + + mapper.JoinedSubclass(rc => + { + rc.Proxy(typeof(IDomesticCat)); + rc.Property(x => x.OwnerName); + }); + + return mapper.CompileMappingForAllExplicitlyAddedEntities(); + } + + protected override void OnSetUp() + { + using (var session = OpenSession()) + using (var transaction = session.BeginTransaction()) + { + catId = session.Save(new Cat { Name = "Bob" }); + + domesticCatId = session.Save(new DomesticCat {Name = "Tom", OwnerName = "Jerry"}); + + transaction.Commit(); + } + } + + protected override void OnTearDown() + { + using (var session = OpenSession()) + using (var transaction = session.BeginTransaction()) + { + session.CreateQuery("delete from System.Object").ExecuteUpdate(); + + transaction.Commit(); + } + } + + [Test] + public void CanLoadDomesticCatUsingBaseClass() + { + using (var session = OpenSession()) + using (session.BeginTransaction()) + { + var cat = session.Load(domesticCatId); + Assert.That(cat, Is.Not.Null); + } + } + + [Test] + public void CanLoadDomesticCatUsingBaseClassInterface() + { + using (var session = OpenSession()) + using (session.BeginTransaction()) + { + var cat = session.Load(domesticCatId); + Assert.That(cat, Is.Not.Null); + } + } + + [Test] + public void CanLoadDomesticCatUsingInterface() + { + using (var session = OpenSession()) + using (session.BeginTransaction()) + { + var cat = session.Load(domesticCatId); + Assert.That(cat, Is.Not.Null); + } + } + + [Test] + public void ThrowWhenTryToLoadDomesticCatUsingSealedClass() + { + using (var session = OpenSession()) + using (session.BeginTransaction()) + { + Assert.Throws(() => session.Load(domesticCatId)); + } + } + + [Test] + public void CanLoadDomesticCatUsingSealedClass() + { + using (var session = OpenSession()) + using (session.BeginTransaction()) + { + var cat = (IDomesticCat) session.Load(typeof(DomesticCat), domesticCatId); + Assert.That(cat, Is.Not.Null); + } + } + + [Test] + public void CanLoadDomesticCatUsingSideInterface() + { + using (var session = OpenSession()) + using (session.BeginTransaction()) + { + var cat = session.Load(domesticCatId); + Assert.That(cat, Is.Not.Null); + } + } + + [Test] + public void CanLoadCatUsingClass() + { + using (var session = OpenSession()) + using (session.BeginTransaction()) + { + var cat = session.Load(catId); + Assert.That(cat, Is.Not.Null); + } + } + + [Test] + public void CanLoadCatUsingInterface() + { + using (var session = OpenSession()) + using (session.BeginTransaction()) + { + var cat = session.Load(catId); + Assert.That(cat, Is.Not.Null); + } + } + } +} diff --git a/src/NHibernate/Proxy/StaticProxyFactory.cs b/src/NHibernate/Proxy/StaticProxyFactory.cs index 278ac748212..d100ac1797d 100644 --- a/src/NHibernate/Proxy/StaticProxyFactory.cs +++ b/src/NHibernate/Proxy/StaticProxyFactory.cs @@ -54,7 +54,21 @@ public override void PostInstantiate( GetIdentifierMethod, SetIdentifierMethod, ComponentIdType); - _cacheEntry = new ProxyCacheEntry(IsClassProxy ? PersistentClass : typeof(object), Interfaces); + _cacheEntry = new ProxyCacheEntry(GetProxyBaseType(PersistentClass), Interfaces); + } + + private static System.Type GetProxyBaseType(System.Type type) + { + if (type.IsClass) + { + for (var t = type; t != null; t = t.BaseType) + { + if (!t.IsSealed) + return t; + } + } + + return typeof(object); } private Func CreateProxyActivator(ProxyCacheEntry pke) From 4789e7f0c8d4ad7e40148260c6ed3baba586070f Mon Sep 17 00:00:00 2001 From: Alexander Zaytsev Date: Tue, 19 Mar 2019 22:21:43 +1300 Subject: [PATCH 2/8] Always use PersistentClass as a base class for proxy Change invocation of IProxyFactory.PostInstantiate to pass correct base class depending on the set interface proxy --- .../NHSpecificTest/GH2067/Fixture.cs | 15 +++++++++++ src/NHibernate/Proxy/StaticProxyFactory.cs | 16 +----------- .../Tuple/Entity/PocoEntityTuplizer.cs | 26 ++++++++++++------- 3 files changed, 32 insertions(+), 25 deletions(-) diff --git a/src/NHibernate.Test/NHSpecificTest/GH2067/Fixture.cs b/src/NHibernate.Test/NHSpecificTest/GH2067/Fixture.cs index 3f72e36f270..f3cefa2333e 100644 --- a/src/NHibernate.Test/NHSpecificTest/GH2067/Fixture.cs +++ b/src/NHibernate.Test/NHSpecificTest/GH2067/Fixture.cs @@ -61,6 +61,10 @@ public void CanLoadDomesticCatUsingBaseClass() { var cat = session.Load(domesticCatId); Assert.That(cat, Is.Not.Null); + Assert.That(cat.Name, Is.EqualTo("Tom")); + var domesticCat = (IDomesticCat) cat; + Assert.That(domesticCat.Name, Is.EqualTo("Tom")); + Assert.That(domesticCat.OwnerName, Is.EqualTo("Jerry")); } } @@ -72,6 +76,10 @@ public void CanLoadDomesticCatUsingBaseClassInterface() { var cat = session.Load(domesticCatId); Assert.That(cat, Is.Not.Null); + Assert.That(cat.Name, Is.EqualTo("Tom")); + var domesticCat = (IDomesticCat) cat; + Assert.That(domesticCat.Name, Is.EqualTo("Tom")); + Assert.That(domesticCat.OwnerName, Is.EqualTo("Jerry")); } } @@ -83,6 +91,8 @@ public void CanLoadDomesticCatUsingInterface() { var cat = session.Load(domesticCatId); Assert.That(cat, Is.Not.Null); + Assert.That(cat.Name, Is.EqualTo("Tom")); + Assert.That(cat.OwnerName, Is.EqualTo("Jerry")); } } @@ -104,6 +114,8 @@ public void CanLoadDomesticCatUsingSealedClass() { var cat = (IDomesticCat) session.Load(typeof(DomesticCat), domesticCatId); Assert.That(cat, Is.Not.Null); + Assert.That(cat.Name, Is.EqualTo("Tom")); + Assert.That(cat.OwnerName, Is.EqualTo("Jerry")); } } @@ -115,6 +127,7 @@ public void CanLoadDomesticCatUsingSideInterface() { var cat = session.Load(domesticCatId); Assert.That(cat, Is.Not.Null); + Assert.That(cat.OwnerName, Is.EqualTo("Jerry")); } } @@ -126,6 +139,7 @@ public void CanLoadCatUsingClass() { var cat = session.Load(catId); Assert.That(cat, Is.Not.Null); + Assert.That(cat.Name, Is.EqualTo("Bob")); } } @@ -137,6 +151,7 @@ public void CanLoadCatUsingInterface() { var cat = session.Load(catId); Assert.That(cat, Is.Not.Null); + Assert.That(cat.Name, Is.EqualTo("Bob")); } } } diff --git a/src/NHibernate/Proxy/StaticProxyFactory.cs b/src/NHibernate/Proxy/StaticProxyFactory.cs index d100ac1797d..a0ff72dffec 100644 --- a/src/NHibernate/Proxy/StaticProxyFactory.cs +++ b/src/NHibernate/Proxy/StaticProxyFactory.cs @@ -54,21 +54,7 @@ public override void PostInstantiate( GetIdentifierMethod, SetIdentifierMethod, ComponentIdType); - _cacheEntry = new ProxyCacheEntry(GetProxyBaseType(PersistentClass), Interfaces); - } - - private static System.Type GetProxyBaseType(System.Type type) - { - if (type.IsClass) - { - for (var t = type; t != null; t = t.BaseType) - { - if (!t.IsSealed) - return t; - } - } - - return typeof(object); + _cacheEntry = new ProxyCacheEntry(PersistentClass, Interfaces); } private Func CreateProxyActivator(ProxyCacheEntry pke) diff --git a/src/NHibernate/Tuple/Entity/PocoEntityTuplizer.cs b/src/NHibernate/Tuple/Entity/PocoEntityTuplizer.cs index 79285ce1ea9..e25a0efa232 100644 --- a/src/NHibernate/Tuple/Entity/PocoEntityTuplizer.cs +++ b/src/NHibernate/Tuple/Entity/PocoEntityTuplizer.cs @@ -108,10 +108,9 @@ protected override IInstantiator BuildInstantiator(PersistentClass persistentCla } } - protected override IProxyFactory BuildProxyFactory(PersistentClass persistentClass, IGetter idGetter, - ISetter idSetter) + protected override IProxyFactory BuildProxyFactory(PersistentClass persistentClass, IGetter idGetter, ISetter idSetter) { - bool needAccesorCheck = true; // NH specific (look the comment below) + bool isInterface = false; // NH specific (look the comment below) // determine the id getter and setter methods from the proxy interface (if any) // determine all interfaces needed by the resulting proxy @@ -120,19 +119,19 @@ protected override IProxyFactory BuildProxyFactory(PersistentClass persistentCla System.Type _mappedClass = persistentClass.MappedClass; System.Type _proxyInterface = persistentClass.ProxyInterface; - if (_proxyInterface != null && !_mappedClass.Equals(_proxyInterface)) + if (_proxyInterface != null && _mappedClass != _proxyInterface) { if (!_proxyInterface.IsInterface) { throw new MappingException("proxy must be either an interface, or the class itself: " + EntityName); } - needAccesorCheck = false; // NH (the proxy is an interface all properties can be overridden) + isInterface = true; // NH (the proxy is an interface all properties can be overridden) proxyInterfaces.Add(_proxyInterface); } if (_mappedClass.IsInterface) { - needAccesorCheck = false; // NH (the mapped class is an interface all properties can be overridden) + isInterface = true; // NH (the mapped class is an interface all properties can be overridden) proxyInterfaces.Add(_mappedClass); } @@ -140,7 +139,7 @@ protected override IProxyFactory BuildProxyFactory(PersistentClass persistentCla { System.Type subclassProxy = subclass.ProxyInterface; System.Type subclassClass = subclass.MappedClass; - if (subclassProxy != null && !subclassClass.Equals(subclassProxy)) + if (subclassProxy != null && subclassClass != subclassProxy) { if (!subclassProxy.IsInterface) { @@ -155,7 +154,7 @@ protected override IProxyFactory BuildProxyFactory(PersistentClass persistentCla * - Check if the logger is enabled * - Don't need nothing to check if the mapped-class or proxy is an interface */ - if (log.IsErrorEnabled() && needAccesorCheck) + if (!isInterface && log.IsErrorEnabled()) { LogPropertyAccessorsErrors(persistentClass); } @@ -173,8 +172,15 @@ protected override IProxyFactory BuildProxyFactory(PersistentClass persistentCla IProxyFactory pf = BuildProxyFactoryInternal(persistentClass, idGetter, idSetter); try { - pf.PostInstantiate(EntityName, _mappedClass, proxyInterfaces, proxyGetIdentifierMethod, proxySetIdentifierMethod, - persistentClass.HasEmbeddedIdentifier ? (IAbstractComponentType) persistentClass.Identifier.Type: null); + pf.PostInstantiate( + EntityName, + isInterface ? typeof(object) : _mappedClass, + proxyInterfaces, + proxyGetIdentifierMethod, + proxySetIdentifierMethod, + persistentClass.HasEmbeddedIdentifier + ? (IAbstractComponentType) persistentClass.Identifier.Type + : null); } catch (HibernateException he) { From b20f638fbbb1cdd131d690e2f4862df6fbd9adf5 Mon Sep 17 00:00:00 2001 From: Alexander Zaytsev Date: Tue, 19 Mar 2019 22:58:44 +1300 Subject: [PATCH 3/8] Pre-calculate IsClassProxy by PocoEntityTuplizer --- .../NHSpecificTest/GH2067/Fixture.cs | 17 ++++++++++++++++- src/NHibernate/Proxy/AbstractProxyFactory.cs | 7 +------ .../Proxy/NHibernateProxyFactoryInfo.cs | 14 +++++++++++++- src/NHibernate/Proxy/StaticProxyFactory.cs | 5 +++-- .../Tuple/Entity/PocoEntityTuplizer.cs | 7 ++++++- 5 files changed, 39 insertions(+), 11 deletions(-) diff --git a/src/NHibernate.Test/NHSpecificTest/GH2067/Fixture.cs b/src/NHibernate.Test/NHSpecificTest/GH2067/Fixture.cs index f3cefa2333e..aac1c4a7828 100644 --- a/src/NHibernate.Test/NHSpecificTest/GH2067/Fixture.cs +++ b/src/NHibernate.Test/NHSpecificTest/GH2067/Fixture.cs @@ -1,6 +1,7 @@ using System; using NHibernate.Cfg.MappingSchema; using NHibernate.Mapping.ByCode; +using NHibernate.Proxy; using NUnit.Framework; namespace NHibernate.Test.NHSpecificTest.GH2067 @@ -65,9 +66,11 @@ public void CanLoadDomesticCatUsingBaseClass() var domesticCat = (IDomesticCat) cat; Assert.That(domesticCat.Name, Is.EqualTo("Tom")); Assert.That(domesticCat.OwnerName, Is.EqualTo("Jerry")); + var proxy = (INHibernateProxy) cat; + Assert.That(proxy.HibernateLazyInitializer.PersistentClass, Is.EqualTo(typeof(Cat))); } } - + [Test] public void CanLoadDomesticCatUsingBaseClassInterface() { @@ -80,6 +83,8 @@ public void CanLoadDomesticCatUsingBaseClassInterface() var domesticCat = (IDomesticCat) cat; Assert.That(domesticCat.Name, Is.EqualTo("Tom")); Assert.That(domesticCat.OwnerName, Is.EqualTo("Jerry")); + var proxy = (INHibernateProxy) cat; + Assert.That(proxy.HibernateLazyInitializer.PersistentClass, Is.EqualTo(typeof(Cat))); } } @@ -93,6 +98,8 @@ public void CanLoadDomesticCatUsingInterface() Assert.That(cat, Is.Not.Null); Assert.That(cat.Name, Is.EqualTo("Tom")); Assert.That(cat.OwnerName, Is.EqualTo("Jerry")); + var proxy = (INHibernateProxy) cat; + Assert.That(proxy.HibernateLazyInitializer.PersistentClass, Is.EqualTo(typeof(DomesticCat))); } } @@ -116,6 +123,8 @@ public void CanLoadDomesticCatUsingSealedClass() Assert.That(cat, Is.Not.Null); Assert.That(cat.Name, Is.EqualTo("Tom")); Assert.That(cat.OwnerName, Is.EqualTo("Jerry")); + var proxy = (INHibernateProxy) cat; + Assert.That(proxy.HibernateLazyInitializer.PersistentClass, Is.EqualTo(typeof(DomesticCat))); } } @@ -128,6 +137,8 @@ public void CanLoadDomesticCatUsingSideInterface() var cat = session.Load(domesticCatId); Assert.That(cat, Is.Not.Null); Assert.That(cat.OwnerName, Is.EqualTo("Jerry")); + var proxy = (INHibernateProxy) cat; + Assert.That(proxy.HibernateLazyInitializer.PersistentClass, Is.EqualTo(typeof(DomesticCat))); } } @@ -140,6 +151,8 @@ public void CanLoadCatUsingClass() var cat = session.Load(catId); Assert.That(cat, Is.Not.Null); Assert.That(cat.Name, Is.EqualTo("Bob")); + var proxy = (INHibernateProxy) cat; + Assert.That(proxy.HibernateLazyInitializer.PersistentClass, Is.EqualTo(typeof(Cat))); } } @@ -152,6 +165,8 @@ public void CanLoadCatUsingInterface() var cat = session.Load(catId); Assert.That(cat, Is.Not.Null); Assert.That(cat.Name, Is.EqualTo("Bob")); + var proxy = (INHibernateProxy) cat; + Assert.That(proxy.HibernateLazyInitializer.PersistentClass, Is.EqualTo(typeof(Cat))); } } } diff --git a/src/NHibernate/Proxy/AbstractProxyFactory.cs b/src/NHibernate/Proxy/AbstractProxyFactory.cs index 39dfd8cab2f..3504658b935 100644 --- a/src/NHibernate/Proxy/AbstractProxyFactory.cs +++ b/src/NHibernate/Proxy/AbstractProxyFactory.cs @@ -19,11 +19,7 @@ public abstract class AbstractProxyFactory: IProxyFactory protected virtual MethodInfo SetIdentifierMethod { get; private set; } protected virtual IAbstractComponentType ComponentIdType { get; private set; } protected virtual bool OverridesEquals { get; set; } - - protected bool IsClassProxy - { - get { return Interfaces.Length == 1; } - } + protected internal bool IsClassProxy { get; internal set; } public virtual void PostInstantiate(string entityName, System.Type persistentClass, ISet interfaces, MethodInfo getIdentifierMethod, MethodInfo setIdentifierMethod, @@ -44,7 +40,6 @@ public virtual void PostInstantiate(string entityName, System.Type persistentCla OverridesEquals = ReflectHelper.OverridesEquals(persistentClass); } - public abstract INHibernateProxy GetProxy(object id, ISessionImplementor session); // Since 5.3 diff --git a/src/NHibernate/Proxy/NHibernateProxyFactoryInfo.cs b/src/NHibernate/Proxy/NHibernateProxyFactoryInfo.cs index 69400454e7e..47ffd2dc67d 100644 --- a/src/NHibernate/Proxy/NHibernateProxyFactoryInfo.cs +++ b/src/NHibernate/Proxy/NHibernateProxyFactoryInfo.cs @@ -16,8 +16,16 @@ public sealed class NHibernateProxyFactoryInfo : ISerializable private readonly MethodInfo _getIdentifierMethod; private readonly MethodInfo _setIdentifierMethod; private readonly IAbstractComponentType _componentIdType; + private readonly bool _isClassProxy; - internal NHibernateProxyFactoryInfo(string entityName, System.Type persistentClass, System.Type[] interfaces, MethodInfo getIdentifierMethod, MethodInfo setIdentifierMethod, IAbstractComponentType componentIdType) + internal NHibernateProxyFactoryInfo( + string entityName, + System.Type persistentClass, + System.Type[] interfaces, + MethodInfo getIdentifierMethod, + MethodInfo setIdentifierMethod, + IAbstractComponentType componentIdType, + bool isClassProxy) { _entityName = entityName; _persistentClass = persistentClass; @@ -25,6 +33,7 @@ internal NHibernateProxyFactoryInfo(string entityName, System.Type persistentCla _getIdentifierMethod = getIdentifierMethod; _setIdentifierMethod = setIdentifierMethod; _componentIdType = componentIdType; + _isClassProxy = isClassProxy; } internal System.Type PersistentClass => _persistentClass; @@ -32,6 +41,7 @@ internal NHibernateProxyFactoryInfo(string entityName, System.Type persistentCla public IProxyFactory CreateProxyFactory() { var factory = new StaticProxyFactory(); + factory.IsClassProxy = _isClassProxy; factory.PostInstantiate(_entityName, _persistentClass, new HashSet(_interfaces), _getIdentifierMethod, _setIdentifierMethod, _componentIdType); return factory; } @@ -44,6 +54,7 @@ private NHibernateProxyFactoryInfo(SerializationInfo info, StreamingContext cont _getIdentifierMethod = (MethodInfo) info.GetValue(nameof(_getIdentifierMethod), typeof(MethodInfo)); _setIdentifierMethod = (MethodInfo) info.GetValue(nameof(_setIdentifierMethod), typeof(MethodInfo)); _componentIdType = (IAbstractComponentType) info.GetValue(nameof(_componentIdType), typeof(IAbstractComponentType)); + _isClassProxy = (bool) info.GetValue(nameof(_isClassProxy), typeof(bool)); } [SecurityCritical] @@ -55,6 +66,7 @@ public void GetObjectData(SerializationInfo info, StreamingContext context) info.AddValue(nameof(_getIdentifierMethod), _getIdentifierMethod); info.AddValue(nameof(_setIdentifierMethod), _setIdentifierMethod); info.AddValue(nameof(_componentIdType), _componentIdType); + info.AddValue(nameof(_isClassProxy), _isClassProxy); } } } diff --git a/src/NHibernate/Proxy/StaticProxyFactory.cs b/src/NHibernate/Proxy/StaticProxyFactory.cs index a0ff72dffec..6ef853e72a5 100644 --- a/src/NHibernate/Proxy/StaticProxyFactory.cs +++ b/src/NHibernate/Proxy/StaticProxyFactory.cs @@ -53,8 +53,9 @@ public override void PostInstantiate( Interfaces, GetIdentifierMethod, SetIdentifierMethod, - ComponentIdType); - _cacheEntry = new ProxyCacheEntry(PersistentClass, Interfaces); + ComponentIdType, + IsClassProxy); + _cacheEntry = new ProxyCacheEntry(IsClassProxy ? PersistentClass : typeof(object), Interfaces); } private Func CreateProxyActivator(ProxyCacheEntry pke) diff --git a/src/NHibernate/Tuple/Entity/PocoEntityTuplizer.cs b/src/NHibernate/Tuple/Entity/PocoEntityTuplizer.cs index e25a0efa232..40110a97fe1 100644 --- a/src/NHibernate/Tuple/Entity/PocoEntityTuplizer.cs +++ b/src/NHibernate/Tuple/Entity/PocoEntityTuplizer.cs @@ -172,9 +172,14 @@ protected override IProxyFactory BuildProxyFactory(PersistentClass persistentCla IProxyFactory pf = BuildProxyFactoryInternal(persistentClass, idGetter, idSetter); try { + if (pf is AbstractProxyFactory apf) + { + apf.IsClassProxy = !isInterface; + } + pf.PostInstantiate( EntityName, - isInterface ? typeof(object) : _mappedClass, + _mappedClass, proxyInterfaces, proxyGetIdentifierMethod, proxySetIdentifierMethod, From 4c6a2cdc8e56c4479e8f5030d01a91e440e6a5de Mon Sep 17 00:00:00 2001 From: Alexander Zaytsev Date: Wed, 20 Mar 2019 10:28:36 +1300 Subject: [PATCH 4/8] Add IsClassProxy initialization to PostInstantiate --- .../StaticProxyFactoryFixture.cs | 29 ++++++++------- src/NHibernate/Proxy/AbstractProxyFactory.cs | 33 +++++++++++++++-- src/NHibernate/Proxy/IProxyFactory.cs | 37 +++++++++++++++++++ src/NHibernate/Proxy/Map/MapProxyFactory.cs | 14 +++++-- .../Proxy/NHibernateProxyFactoryInfo.cs | 10 ++++- src/NHibernate/Proxy/StaticProxyFactory.cs | 5 ++- .../Tuple/Entity/DynamicMapEntityTuplizer.cs | 16 +------- .../Tuple/Entity/PocoEntityTuplizer.cs | 9 +---- 8 files changed, 107 insertions(+), 46 deletions(-) diff --git a/src/NHibernate.Test/StaticProxyTest/StaticProxyFactoryFixture.cs b/src/NHibernate.Test/StaticProxyTest/StaticProxyFactoryFixture.cs index abd159bf11b..1977b3f4049 100644 --- a/src/NHibernate.Test/StaticProxyTest/StaticProxyFactoryFixture.cs +++ b/src/NHibernate.Test/StaticProxyTest/StaticProxyFactoryFixture.cs @@ -176,7 +176,7 @@ protected virtual void GetObjectData(SerializationInfo info, StreamingContext co public void VerifyProxyForClassWithInternalInterface() { var factory = new StaticProxyFactory(); - factory.PostInstantiate(typeof(InternalInterfaceTestClass).FullName, typeof(InternalInterfaceTestClass), new HashSet {typeof(INHibernateProxy)}, null, null, null); + factory.PostInstantiate(typeof(InternalInterfaceTestClass).FullName, typeof(InternalInterfaceTestClass), new HashSet {typeof(INHibernateProxy)}, null, null, null, true); #if NETFX VerifyGeneratedAssembly( @@ -202,7 +202,7 @@ public void VerifyProxyForClassWithAdditionalInterface() // having an additional interface in the interface list, instead of just having INHibernateProxy. // (Quite a loose semantic...) new HashSet { typeof(INHibernateProxy), typeof(IPublic) }, - null, null, null); + null, null, null, false); #if NETFX VerifyGeneratedAssembly( @@ -226,7 +226,7 @@ public void VerifyProxyForClassWithInterface() typeof(PublicInterfaceTestClass).FullName, typeof(PublicInterfaceTestClass), new HashSet {typeof(INHibernateProxy)}, - null, null, null); + null, null, null, true); #if NETFX VerifyGeneratedAssembly( @@ -266,7 +266,7 @@ public void VerifyProxyForClassWithExplicitInterface() typeof(PublicExplicitInterfaceTestClass).FullName, typeof(PublicExplicitInterfaceTestClass), new HashSet {typeof(INHibernateProxy)}, - null, null, null); + null, null, null, true); #if NETFX VerifyGeneratedAssembly( () => @@ -307,7 +307,8 @@ public void VerifyProxyForRefOutClass() new HashSet { typeof(INHibernateProxy) }, null, null, - null); + null, + true); #if NETFX VerifyGeneratedAssembly( @@ -350,7 +351,7 @@ public void VerifyProxyForAbstractClass() typeof(AbstractTestClass).FullName, typeof(AbstractTestClass), new HashSet { typeof(INHibernateProxy) }, - null, null, null); + null, null, null, true); #if NETFX VerifyGeneratedAssembly( @@ -370,7 +371,7 @@ public void VerifyProxyForAbstractClass() public void InitializedProxyStaysInitializedAfterDeserialization() { var factory = new StaticProxyFactory(); - factory.PostInstantiate(typeof(SimpleTestClass).FullName, typeof(SimpleTestClass), new HashSet {typeof(INHibernateProxy)}, null, null, null); + factory.PostInstantiate(typeof(SimpleTestClass).FullName, typeof(SimpleTestClass), new HashSet {typeof(INHibernateProxy)}, null, null, null, true); var proxy = factory.GetProxy(2, null); Assert.That(proxy, Is.Not.Null, "proxy"); Assert.That(NHibernateUtil.IsInitialized(proxy), Is.False, "proxy already initialized after creation"); @@ -399,7 +400,7 @@ public void InitializedProxyStaysInitializedAfterDeserialization() public void NonInitializedProxyStaysNonInitializedAfterSerialization() { var factory = new StaticProxyFactory(); - factory.PostInstantiate(typeof(SimpleTestClass).FullName, typeof(SimpleTestClass), new HashSet {typeof(INHibernateProxy)}, null, null, null); + factory.PostInstantiate(typeof(SimpleTestClass).FullName, typeof(SimpleTestClass), new HashSet {typeof(INHibernateProxy)}, null, null, null, true); var proxy = factory.GetProxy(2, null); Assert.That(proxy, Is.Not.Null, "proxy"); Assert.That(NHibernateUtil.IsInitialized(proxy), Is.False, "proxy already initialized after creation"); @@ -422,7 +423,7 @@ public void NonInitializedProxyStaysNonInitializedAfterSerialization() public void CanSerializeFieldInterceptorProxy() { var factory = new StaticProxyFactory(); - factory.PostInstantiate(typeof(PublicInterfaceTestClass).FullName, typeof(PublicInterfaceTestClass), new HashSet {typeof(INHibernateProxy)}, null, null, null); + factory.PostInstantiate(typeof(PublicInterfaceTestClass).FullName, typeof(PublicInterfaceTestClass), new HashSet {typeof(INHibernateProxy)}, null, null, null, true); var proxy = (PublicInterfaceTestClass) factory.GetFieldInterceptionProxy(); proxy.Id = 1; @@ -440,7 +441,7 @@ public void CanSerializeFieldInterceptorProxy() public void CanSerializeFieldInterceptorProxyWithISerializableEntity() { var factory = new StaticProxyFactory(); - factory.PostInstantiate(typeof(CustomSerializationClass).FullName, typeof(CustomSerializationClass), new HashSet {typeof(INHibernateProxy)}, null, null, null); + factory.PostInstantiate(typeof(CustomSerializationClass).FullName, typeof(CustomSerializationClass), new HashSet {typeof(INHibernateProxy)}, null, null, null, true); var proxy = (CustomSerializationClass) factory.GetFieldInterceptionProxy(); proxy.Id = 2; @@ -458,7 +459,7 @@ public void CanSerializeFieldInterceptorProxyWithISerializableEntity() public void CanSerializeFieldInterceptorProxyWithExplicitISerializableEntity() { var factory = new StaticProxyFactory(); - factory.PostInstantiate(typeof(CustomExplicitSerializationClass).FullName, typeof(CustomExplicitSerializationClass), new HashSet {typeof(INHibernateProxy)}, null, null, null); + factory.PostInstantiate(typeof(CustomExplicitSerializationClass).FullName, typeof(CustomExplicitSerializationClass), new HashSet {typeof(INHibernateProxy)}, null, null, null, true); var proxy = (CustomExplicitSerializationClass) factory.GetFieldInterceptionProxy(); proxy.Id = 2; @@ -476,7 +477,7 @@ public void CanSerializeFieldInterceptorProxyWithExplicitISerializableEntity() public void VerifyFieldInterceptorProxy() { var factory = new StaticProxyFactory(); - factory.PostInstantiate(typeof(InternalInterfaceTestClass).FullName, typeof(InternalInterfaceTestClass), new HashSet {typeof(INHibernateProxy)}, null, null, null); + factory.PostInstantiate(typeof(InternalInterfaceTestClass).FullName, typeof(InternalInterfaceTestClass), new HashSet {typeof(INHibernateProxy)}, null, null, null, true); #if NETFX VerifyGeneratedAssembly( () => @@ -493,7 +494,7 @@ public void VerifyFieldInterceptorProxy() public void VerifyFieldInterceptorProxyWithISerializableEntity() { var factory = new StaticProxyFactory(); - factory.PostInstantiate(typeof(CustomSerializationClass).FullName, typeof(CustomSerializationClass), new HashSet {typeof(INHibernateProxy)}, null, null, null); + factory.PostInstantiate(typeof(CustomSerializationClass).FullName, typeof(CustomSerializationClass), new HashSet {typeof(INHibernateProxy)}, null, null, null, true); #if NETFX VerifyGeneratedAssembly( () => @@ -521,7 +522,7 @@ public void VerifyFieldInterceptorProxyWithAdditionalInterface() // to an instance of the persistentClass, and so cannot implement interface methods if it does not // inherit the persistentClass. new HashSet {typeof(INHibernateProxy), typeof(IPublic)}, - null, null, null); + null, null, null, false); #if NETFX VerifyGeneratedAssembly( () => diff --git a/src/NHibernate/Proxy/AbstractProxyFactory.cs b/src/NHibernate/Proxy/AbstractProxyFactory.cs index 3504658b935..53357329170 100644 --- a/src/NHibernate/Proxy/AbstractProxyFactory.cs +++ b/src/NHibernate/Proxy/AbstractProxyFactory.cs @@ -18,12 +18,17 @@ public abstract class AbstractProxyFactory: IProxyFactory protected virtual MethodInfo GetIdentifierMethod { get; private set; } protected virtual MethodInfo SetIdentifierMethod { get; private set; } protected virtual IAbstractComponentType ComponentIdType { get; private set; } + protected virtual bool IsClassProxy { get; private set; } protected virtual bool OverridesEquals { get; set; } - protected internal bool IsClassProxy { get; internal set; } - public virtual void PostInstantiate(string entityName, System.Type persistentClass, ISet interfaces, - MethodInfo getIdentifierMethod, MethodInfo setIdentifierMethod, - IAbstractComponentType componentIdType) + public virtual void PostInstantiate( + string entityName, + System.Type persistentClass, + ISet interfaces, + MethodInfo getIdentifierMethod, + MethodInfo setIdentifierMethod, + IAbstractComponentType componentIdType, + bool isClassProxy) { EntityName = entityName; PersistentClass = persistentClass; @@ -38,6 +43,26 @@ public virtual void PostInstantiate(string entityName, System.Type persistentCla SetIdentifierMethod = setIdentifierMethod; ComponentIdType = componentIdType; OverridesEquals = ReflectHelper.OverridesEquals(persistentClass); + IsClassProxy = isClassProxy; + } + + [Obsolete("Override PostInstantiate method with isClassProxy parameter instead.")] + public virtual void PostInstantiate( + string entityName, + System.Type persistentClass, + ISet interfaces, + MethodInfo getIdentifierMethod, + MethodInfo setIdentifierMethod, + IAbstractComponentType componentIdType) + { + PostInstantiate( + entityName, + persistentClass, + interfaces, + getIdentifierMethod, + setIdentifierMethod, + componentIdType, + interfaces.Count == 1); } public abstract INHibernateProxy GetProxy(object id, ISessionImplementor session); diff --git a/src/NHibernate/Proxy/IProxyFactory.cs b/src/NHibernate/Proxy/IProxyFactory.cs index 5e75428a55b..d0cd91189a7 100644 --- a/src/NHibernate/Proxy/IProxyFactory.cs +++ b/src/NHibernate/Proxy/IProxyFactory.cs @@ -38,6 +38,7 @@ public interface IProxyFactory /// Essentially equivalent to constructor injection, but contracted /// here via interface. /// + [Obsolete("Use ProxyFactoryExtensions.PostInstantiate extension method instead.")] void PostInstantiate(string entityName, System.Type persistentClass, ISet interfaces, MethodInfo getIdentifierMethod, MethodInfo setIdentifierMethod, IAbstractComponentType componentIdType); @@ -82,5 +83,41 @@ public static object GetFieldInterceptionProxy(this IProxyFactory proxyFactory) return proxyFactory.GetFieldInterceptionProxy(null); #pragma warning restore 618 } + + // 6.0 TODO: Move to IProxyFactory + public static void PostInstantiate( + this IProxyFactory pf, + string entityName, + System.Type persistentClass, + HashSet interfaces, + MethodInfo getIdentifierMethod, + MethodInfo setIdentifierMethod, + IAbstractComponentType componentIdType, + bool isClassProxy) + { + if (pf is AbstractProxyFactory apf) + { + apf.PostInstantiate( + entityName, + persistentClass, + interfaces, + getIdentifierMethod, + setIdentifierMethod, + componentIdType, + isClassProxy); + } + else + { +#pragma warning disable 618 + pf.PostInstantiate( + entityName, + persistentClass, + interfaces, + getIdentifierMethod, + setIdentifierMethod, + componentIdType); +#pragma warning restore 618 + } + } } } diff --git a/src/NHibernate/Proxy/Map/MapProxyFactory.cs b/src/NHibernate/Proxy/Map/MapProxyFactory.cs index 1e6a1f18006..313f410b649 100644 --- a/src/NHibernate/Proxy/Map/MapProxyFactory.cs +++ b/src/NHibernate/Proxy/Map/MapProxyFactory.cs @@ -10,12 +10,22 @@ public class MapProxyFactory : IProxyFactory { private string entityName; - #region IProxyFactory Members + [Obsolete("Please use constructor accepting entityName instead.")] + public MapProxyFactory() + { + } + public MapProxyFactory(string entityName) + { + this.entityName = entityName; + } + + [Obsolete("Please use constructor accepting entityName instead.")] public void PostInstantiate(string entityName, System.Type persistentClass, ISet interfaces, MethodInfo getIdentifierMethod, MethodInfo setIdentifierMethod, IAbstractComponentType componentIdType) { + //6.0 TODO: throw NotSupportedException this.entityName = entityName; } @@ -28,7 +38,5 @@ public object GetFieldInterceptionProxy(object getInstance) { throw new NotSupportedException(); } - - #endregion } } diff --git a/src/NHibernate/Proxy/NHibernateProxyFactoryInfo.cs b/src/NHibernate/Proxy/NHibernateProxyFactoryInfo.cs index 47ffd2dc67d..70f3af1e2c9 100644 --- a/src/NHibernate/Proxy/NHibernateProxyFactoryInfo.cs +++ b/src/NHibernate/Proxy/NHibernateProxyFactoryInfo.cs @@ -41,8 +41,14 @@ internal NHibernateProxyFactoryInfo( public IProxyFactory CreateProxyFactory() { var factory = new StaticProxyFactory(); - factory.IsClassProxy = _isClassProxy; - factory.PostInstantiate(_entityName, _persistentClass, new HashSet(_interfaces), _getIdentifierMethod, _setIdentifierMethod, _componentIdType); + factory.PostInstantiate( + _entityName, + _persistentClass, + new HashSet(_interfaces), + _getIdentifierMethod, + _setIdentifierMethod, + _componentIdType, + _isClassProxy); return factory; } diff --git a/src/NHibernate/Proxy/StaticProxyFactory.cs b/src/NHibernate/Proxy/StaticProxyFactory.cs index 6ef853e72a5..fa324ea574a 100644 --- a/src/NHibernate/Proxy/StaticProxyFactory.cs +++ b/src/NHibernate/Proxy/StaticProxyFactory.cs @@ -43,9 +43,10 @@ public override void PostInstantiate( ISet interfaces, MethodInfo getIdentifierMethod, MethodInfo setIdentifierMethod, - IAbstractComponentType componentIdType) + IAbstractComponentType componentIdType, + bool isClassProxy) { - base.PostInstantiate(entityName, persistentClass, interfaces, getIdentifierMethod, setIdentifierMethod, componentIdType); + base.PostInstantiate(entityName, persistentClass, interfaces, getIdentifierMethod, setIdentifierMethod, componentIdType, isClassProxy); _proxyFactoryInfo = new NHibernateProxyFactoryInfo( EntityName, diff --git a/src/NHibernate/Tuple/Entity/DynamicMapEntityTuplizer.cs b/src/NHibernate/Tuple/Entity/DynamicMapEntityTuplizer.cs index 9efd2af386f..07abc64fce3 100644 --- a/src/NHibernate/Tuple/Entity/DynamicMapEntityTuplizer.cs +++ b/src/NHibernate/Tuple/Entity/DynamicMapEntityTuplizer.cs @@ -60,21 +60,9 @@ protected override IInstantiator BuildInstantiator(PersistentClass mappingInfo) return new DynamicEntityInstantiator(mappingInfo); } - protected override IProxyFactory BuildProxyFactory(PersistentClass mappingInfo, IGetter idGetter, - ISetter idSetter) + protected override IProxyFactory BuildProxyFactory(PersistentClass mappingInfo, IGetter idGetter, ISetter idSetter) { - IProxyFactory pf = new MapProxyFactory(); - try - { - //TODO: design new lifecycle for ProxyFactory - pf.PostInstantiate(EntityName, null, null, null, null, null); - } - catch (HibernateException he) - { - log.Warn(he, "could not create proxy factory for:{0}", EntityName); - pf = null; - } - return pf; + return new MapProxyFactory(EntityName); } } } diff --git a/src/NHibernate/Tuple/Entity/PocoEntityTuplizer.cs b/src/NHibernate/Tuple/Entity/PocoEntityTuplizer.cs index 40110a97fe1..e45d74a3edf 100644 --- a/src/NHibernate/Tuple/Entity/PocoEntityTuplizer.cs +++ b/src/NHibernate/Tuple/Entity/PocoEntityTuplizer.cs @@ -5,7 +5,6 @@ using NHibernate.Bytecode; using NHibernate.Classic; using NHibernate.Engine; -using NHibernate.Intercept; using NHibernate.Mapping; using NHibernate.Properties; using NHibernate.Proxy; @@ -172,11 +171,6 @@ protected override IProxyFactory BuildProxyFactory(PersistentClass persistentCla IProxyFactory pf = BuildProxyFactoryInternal(persistentClass, idGetter, idSetter); try { - if (pf is AbstractProxyFactory apf) - { - apf.IsClassProxy = !isInterface; - } - pf.PostInstantiate( EntityName, _mappedClass, @@ -185,7 +179,8 @@ protected override IProxyFactory BuildProxyFactory(PersistentClass persistentCla proxySetIdentifierMethod, persistentClass.HasEmbeddedIdentifier ? (IAbstractComponentType) persistentClass.Identifier.Type - : null); + : null, + !isInterface); } catch (HibernateException he) { From 4eb72bfc54f47b64d6e7caf7165e2df3aa09ad3d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Delaporte?= <12201973+fredericdelaporte@users.noreply.github.com> Date: Wed, 20 Mar 2019 01:49:27 +0100 Subject: [PATCH 5/8] Fix SQL-ServerCE failures and regen Async. To be squashed. --- .../BaseAndDerivedClassProxiesFixture.cs | 85 ++++++++ ...eClassAndDerivedInterfaceProxiesFixture.cs | 93 +++++++++ ...ed1InterfaceDerived2ClassProxiesFixture.cs | 89 +++++++++ ...eInterfaceAndDerivedClassProxiesFixture.cs | 86 ++++++++ .../Async/NHSpecificTest/GH2067/Fixture.cs | 186 ++++++++++++++++++ .../NHSpecificTest/GH2067/Fixture.cs | 4 +- 6 files changed, 542 insertions(+), 1 deletion(-) create mode 100644 src/NHibernate.Test/Async/NHSpecificTest/GH2067/BaseAndDerivedClassProxiesFixture.cs create mode 100644 src/NHibernate.Test/Async/NHSpecificTest/GH2067/BaseClassAndDerivedInterfaceProxiesFixture.cs create mode 100644 src/NHibernate.Test/Async/NHSpecificTest/GH2067/BaseClassDerived1InterfaceDerived2ClassProxiesFixture.cs create mode 100644 src/NHibernate.Test/Async/NHSpecificTest/GH2067/BaseInterfaceAndDerivedClassProxiesFixture.cs create mode 100644 src/NHibernate.Test/Async/NHSpecificTest/GH2067/Fixture.cs diff --git a/src/NHibernate.Test/Async/NHSpecificTest/GH2067/BaseAndDerivedClassProxiesFixture.cs b/src/NHibernate.Test/Async/NHSpecificTest/GH2067/BaseAndDerivedClassProxiesFixture.cs new file mode 100644 index 00000000000..dab1548dfc5 --- /dev/null +++ b/src/NHibernate.Test/Async/NHSpecificTest/GH2067/BaseAndDerivedClassProxiesFixture.cs @@ -0,0 +1,85 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by AsyncGenerator. +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + + +using System; +using NHibernate.Cfg.MappingSchema; +using NHibernate.Mapping.ByCode; +using NUnit.Framework; + +namespace NHibernate.Test.NHSpecificTest.GH2067 +{ + using System.Threading.Tasks; + namespace BaseAndDerivedClassProxies + { + using System.Threading.Tasks; + + [TestFixture] + public class BaseAndDerivedClassProxiesFixtureAsync : TestCaseMappingByCode + { + private Guid _id = Guid.NewGuid(); + + protected override HbmMapping GetMappings() + { + var mapper = new ModelMapper(); + mapper.Class( + rc => + { + rc.Id(x => x.Id, m => m.Generator(Generators.GuidComb)); + rc.Property(x => x.BaseName); + }); + + mapper.JoinedSubclass( + rc => { rc.Property(x => x.Derived1Name); }); + + mapper.JoinedSubclass( + rc => { rc.Property(x => x.Derived2Name); }); + + return mapper.CompileMappingForAllExplicitlyAddedEntities(); + } + + [Test] + public async Task ProxyForBaseAsync() + { + using (var s = OpenSession()) + { + var b = await (s.LoadAsync(_id)); + Assert.That(b.Id, Is.EqualTo(_id)); + } + } + + [Test] + public async Task ProxyForDerived1Async() + { + using (var s = OpenSession()) + { + var b = await (s.LoadAsync(typeof(Derived1), _id)); + + Assert.That(b, Is.InstanceOf(typeof(Derived1))); + Assert.That(b, Is.InstanceOf(typeof(Base))); + Assert.That(((Derived1) b).Id, Is.EqualTo(_id)); + } + } + + [Test] + public async Task ProxyForDerived2Async() + { + using (var s = OpenSession()) + { + var b = await (s.LoadAsync(typeof(Derived2), _id)); + + Assert.That(b, Is.InstanceOf(typeof(Derived1))); + Assert.That(b, Is.InstanceOf(typeof(Derived2))); + Assert.That(b, Is.InstanceOf(typeof(Base))); + Assert.That(((Derived2) b).Id, Is.EqualTo(_id)); + } + } + } + } +} diff --git a/src/NHibernate.Test/Async/NHSpecificTest/GH2067/BaseClassAndDerivedInterfaceProxiesFixture.cs b/src/NHibernate.Test/Async/NHSpecificTest/GH2067/BaseClassAndDerivedInterfaceProxiesFixture.cs new file mode 100644 index 00000000000..f18044468b2 --- /dev/null +++ b/src/NHibernate.Test/Async/NHSpecificTest/GH2067/BaseClassAndDerivedInterfaceProxiesFixture.cs @@ -0,0 +1,93 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by AsyncGenerator. +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + + +using System; +using NHibernate.Cfg.MappingSchema; +using NHibernate.Mapping.ByCode; +using NUnit.Framework; + +namespace NHibernate.Test.NHSpecificTest.GH2067 +{ + using System.Threading.Tasks; + namespace BaseClassAndDerivedInterfaceProxies + { + using System.Threading.Tasks; + + [TestFixture] + public class BaseClassAndDerivedInterfaceProxiesFixtureAsync : TestCaseMappingByCode + { + private Guid _id = Guid.NewGuid(); + + protected override HbmMapping GetMappings() + { + var mapper = new ModelMapper(); + mapper.Class( + rc => + { + rc.Id(x => x.Id, m => m.Generator(Generators.GuidComb)); + rc.Property(x => x.BaseName); + }); + + mapper.JoinedSubclass( + rc => + { + rc.Proxy(typeof(IDerived1)); + rc.Property(x => x.Derived1Name); + }); + + mapper.JoinedSubclass( + rc => + { + rc.Proxy(typeof(IDerived2)); + rc.Property(x => x.Derived2Name); + }); + + return mapper.CompileMappingForAllExplicitlyAddedEntities(); + } + + [Test] + public async Task ProxyForBaseClassAsync() + { + using (var s = OpenSession()) + { + var b = await (s.LoadAsync(_id)); + Assert.That(b.Id, Is.EqualTo(_id)); + } + } + + [Test] + public async Task ProxyForDerived1InterfaceAsync() + { + using (var s = OpenSession()) + { + var b = await (s.LoadAsync(typeof(Derived1Interface), _id)); + + Assert.That(b, Is.InstanceOf(typeof(IDerived1))); +// Assert.That(b, Is.InstanceOf(typeof(Base))); + Assert.That(((IDerived1) b).Id, Is.EqualTo(_id)); + } + } + + [Test] + public async Task ProxyForDerived2InterfaceAsync() + { + using (var s = OpenSession()) + { + var b = await (s.LoadAsync(typeof(Derived2Interface), _id)); + + Assert.That(b, Is.InstanceOf(typeof(IDerived2))); +// Assert.That(b, Is.InstanceOf(typeof(IDerived1))); +// Assert.That(b, Is.InstanceOf(typeof(Base))); + Assert.That(((IDerived2) b).Id, Is.EqualTo(_id)); + } + } + } + } +} diff --git a/src/NHibernate.Test/Async/NHSpecificTest/GH2067/BaseClassDerived1InterfaceDerived2ClassProxiesFixture.cs b/src/NHibernate.Test/Async/NHSpecificTest/GH2067/BaseClassDerived1InterfaceDerived2ClassProxiesFixture.cs new file mode 100644 index 00000000000..b06c20b567c --- /dev/null +++ b/src/NHibernate.Test/Async/NHSpecificTest/GH2067/BaseClassDerived1InterfaceDerived2ClassProxiesFixture.cs @@ -0,0 +1,89 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by AsyncGenerator. +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + + +using System; +using NHibernate.Cfg.MappingSchema; +using NHibernate.Mapping.ByCode; +using NUnit.Framework; + +namespace NHibernate.Test.NHSpecificTest.GH2067 +{ + using System.Threading.Tasks; + namespace BaseClassDerived1InterfaceDerived2ClassProxies + { + using System.Threading.Tasks; + + [TestFixture] + public class BaseClassDerived1InterfaceDerived2ClassProxiesFixtureAsync : TestCaseMappingByCode + { + private Guid _id = Guid.NewGuid(); + + protected override HbmMapping GetMappings() + { + var mapper = new ModelMapper(); + mapper.Class( + rc => + { + rc.Id(x => x.Id, m => m.Generator(Generators.GuidComb)); + rc.Property(x => x.BaseName); + }); + + mapper.JoinedSubclass( + rc => + { + rc.Proxy(typeof(IDerived1)); + rc.Property(x => x.Derived1Name); + }); + + mapper.JoinedSubclass( + rc => { rc.Property(x => x.Derived2Name); }); + + return mapper.CompileMappingForAllExplicitlyAddedEntities(); + } + + [Test] + public async Task ProxyForBaseAsync() + { + using (var s = OpenSession()) + { + var b = await (s.LoadAsync(typeof(Base), _id)); + Assert.That(((Base) b).Id, Is.EqualTo(_id)); + } + } + + [Test] + public async Task ProxyForDerived1InterfaceAsync() + { + using (var s = OpenSession()) + { + var b = await (s.LoadAsync(typeof(Derived1), _id)); + + Assert.That(b, Is.InstanceOf(typeof(IDerived1))); + //Assert.That(b, Is.InstanceOf(typeof(Base))); + Assert.That(((IDerived1) b).Id, Is.EqualTo(_id)); + } + } + + [Test] + public async Task ProxyForDerived2Async() + { + using (var s = OpenSession()) + { + var b = await (s.LoadAsync(typeof(Derived2), _id)); + + Assert.That(b, Is.InstanceOf(typeof(IDerived1))); + Assert.That(b, Is.InstanceOf(typeof(Derived2))); + Assert.That(b, Is.InstanceOf(typeof(Base))); + Assert.That(((Derived2) b).Id, Is.EqualTo(_id)); + } + } + } + } +} diff --git a/src/NHibernate.Test/Async/NHSpecificTest/GH2067/BaseInterfaceAndDerivedClassProxiesFixture.cs b/src/NHibernate.Test/Async/NHSpecificTest/GH2067/BaseInterfaceAndDerivedClassProxiesFixture.cs new file mode 100644 index 00000000000..6e2d1c5aa04 --- /dev/null +++ b/src/NHibernate.Test/Async/NHSpecificTest/GH2067/BaseInterfaceAndDerivedClassProxiesFixture.cs @@ -0,0 +1,86 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by AsyncGenerator. +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + + +using System; +using NHibernate.Cfg.MappingSchema; +using NHibernate.Mapping.ByCode; +using NUnit.Framework; + +namespace NHibernate.Test.NHSpecificTest.GH2067 +{ + using System.Threading.Tasks; + namespace BaseInterfaceAndDerivedClassProxies + { + using System.Threading.Tasks; + + [TestFixture] + public class BaseInterfaceAndDerivedClassProxiesFixtureAsync : TestCaseMappingByCode + { + private Guid _id = Guid.NewGuid(); + + protected override HbmMapping GetMappings() + { + var mapper = new ModelMapper(); + mapper.Class( + rc => + { + rc.Proxy(typeof(IBase)); + rc.Id(x => x.Id, m => m.Generator(Generators.GuidComb)); + rc.Property(x => x.BaseName); + }); + + mapper.JoinedSubclass( + rc => { rc.Property(x => x.Derived1Name); }); + + mapper.JoinedSubclass( + rc => { rc.Property(x => x.Derived2Name); }); + + return mapper.CompileMappingForAllExplicitlyAddedEntities(); + } + + [Test] + public async Task ProxyForBaseAsync() + { + using (var s = OpenSession()) + { + var b = await (s.LoadAsync(typeof(IBase), _id)); + Assert.That(((IBase) b).Id, Is.EqualTo(_id)); + } + } + + [Test] + public async Task ProxyForDerived1Async() + { + using (var s = OpenSession()) + { + var b = await (s.LoadAsync(typeof(Derived1), _id)); + + Assert.That(b, Is.InstanceOf(typeof(Derived1))); + Assert.That(b, Is.InstanceOf(typeof(IBase))); + Assert.That(((Derived1) b).Id, Is.EqualTo(_id)); + } + } + + [Test] + public async Task ProxyForDerived2Async() + { + using (var s = OpenSession()) + { + var b = await (s.LoadAsync(typeof(Derived2), _id)); + + Assert.That(b, Is.InstanceOf(typeof(Derived1))); + Assert.That(b, Is.InstanceOf(typeof(Derived2))); + Assert.That(b, Is.InstanceOf(typeof(IBase))); + Assert.That(((Derived2) b).Id, Is.EqualTo(_id)); + } + } + } + } +} diff --git a/src/NHibernate.Test/Async/NHSpecificTest/GH2067/Fixture.cs b/src/NHibernate.Test/Async/NHSpecificTest/GH2067/Fixture.cs new file mode 100644 index 00000000000..42587b26b01 --- /dev/null +++ b/src/NHibernate.Test/Async/NHSpecificTest/GH2067/Fixture.cs @@ -0,0 +1,186 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by AsyncGenerator. +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + + +using System; +using NHibernate.Cfg.MappingSchema; +using NHibernate.Mapping.ByCode; +using NHibernate.Proxy; +using NUnit.Framework; + +namespace NHibernate.Test.NHSpecificTest.GH2067 +{ + using System.Threading.Tasks; + [TestFixture] + public class FixtureAsync : TestCaseMappingByCode + { + private object domesticCatId; + private object catId; + + protected override HbmMapping GetMappings() + { + var mapper = new ModelMapper(); + mapper.Class(rc => + { + rc.Id(x => x.Id, m => m.Generator(Generators.GuidComb)); + rc.Property(x => x.Name); + }); + + mapper.JoinedSubclass(rc => + { + rc.Proxy(typeof(IDomesticCat)); + rc.Property(x => x.OwnerName); + }); + + return mapper.CompileMappingForAllExplicitlyAddedEntities(); + } + + protected override void OnSetUp() + { + using (var session = OpenSession()) + using (var transaction = session.BeginTransaction()) + { + catId = session.Save(new Cat { Name = "Bob" }); + + domesticCatId = session.Save(new DomesticCat {Name = "Tom", OwnerName = "Jerry"}); + + transaction.Commit(); + } + } + + protected override void OnTearDown() + { + using (var session = OpenSession()) + using (var transaction = session.BeginTransaction()) + { + // HQL Delete of entities with joins require temp tables, which are not + // supported by all dialects: use in memory-delete instead. + session.Delete("from System.Object"); + + transaction.Commit(); + } + } + + [Test] + public async Task CanLoadDomesticCatUsingBaseClassAsync() + { + using (var session = OpenSession()) + using (session.BeginTransaction()) + { + var cat = await (session.LoadAsync(domesticCatId)); + Assert.That(cat, Is.Not.Null); + Assert.That(cat.Name, Is.EqualTo("Tom")); + var domesticCat = (IDomesticCat) cat; + Assert.That(domesticCat.Name, Is.EqualTo("Tom")); + Assert.That(domesticCat.OwnerName, Is.EqualTo("Jerry")); + var proxy = (INHibernateProxy) cat; + Assert.That(proxy.HibernateLazyInitializer.PersistentClass, Is.EqualTo(typeof(Cat))); + } + } + + [Test] + public async Task CanLoadDomesticCatUsingBaseClassInterfaceAsync() + { + using (var session = OpenSession()) + using (session.BeginTransaction()) + { + var cat = await (session.LoadAsync(domesticCatId)); + Assert.That(cat, Is.Not.Null); + Assert.That(cat.Name, Is.EqualTo("Tom")); + var domesticCat = (IDomesticCat) cat; + Assert.That(domesticCat.Name, Is.EqualTo("Tom")); + Assert.That(domesticCat.OwnerName, Is.EqualTo("Jerry")); + var proxy = (INHibernateProxy) cat; + Assert.That(proxy.HibernateLazyInitializer.PersistentClass, Is.EqualTo(typeof(Cat))); + } + } + + [Test] + public async Task CanLoadDomesticCatUsingInterfaceAsync() + { + using (var session = OpenSession()) + using (session.BeginTransaction()) + { + var cat = await (session.LoadAsync(domesticCatId)); + Assert.That(cat, Is.Not.Null); + Assert.That(cat.Name, Is.EqualTo("Tom")); + Assert.That(cat.OwnerName, Is.EqualTo("Jerry")); + var proxy = (INHibernateProxy) cat; + Assert.That(proxy.HibernateLazyInitializer.PersistentClass, Is.EqualTo(typeof(DomesticCat))); + } + } + + [Test] + public void ThrowWhenTryToLoadDomesticCatUsingSealedClassAsync() + { + using (var session = OpenSession()) + using (session.BeginTransaction()) + { + Assert.ThrowsAsync(() => session.LoadAsync(domesticCatId)); + } + } + + [Test] + public async Task CanLoadDomesticCatUsingSealedClassAsync() + { + using (var session = OpenSession()) + using (session.BeginTransaction()) + { + var cat = (IDomesticCat) await (session.LoadAsync(typeof(DomesticCat), domesticCatId)); + Assert.That(cat, Is.Not.Null); + Assert.That(cat.Name, Is.EqualTo("Tom")); + Assert.That(cat.OwnerName, Is.EqualTo("Jerry")); + var proxy = (INHibernateProxy) cat; + Assert.That(proxy.HibernateLazyInitializer.PersistentClass, Is.EqualTo(typeof(DomesticCat))); + } + } + + [Test] + public async Task CanLoadDomesticCatUsingSideInterfaceAsync() + { + using (var session = OpenSession()) + using (session.BeginTransaction()) + { + var cat = await (session.LoadAsync(domesticCatId)); + Assert.That(cat, Is.Not.Null); + Assert.That(cat.OwnerName, Is.EqualTo("Jerry")); + var proxy = (INHibernateProxy) cat; + Assert.That(proxy.HibernateLazyInitializer.PersistentClass, Is.EqualTo(typeof(DomesticCat))); + } + } + + [Test] + public async Task CanLoadCatUsingClassAsync() + { + using (var session = OpenSession()) + using (session.BeginTransaction()) + { + var cat = await (session.LoadAsync(catId)); + Assert.That(cat, Is.Not.Null); + Assert.That(cat.Name, Is.EqualTo("Bob")); + var proxy = (INHibernateProxy) cat; + Assert.That(proxy.HibernateLazyInitializer.PersistentClass, Is.EqualTo(typeof(Cat))); + } + } + + [Test] + public async Task CanLoadCatUsingInterfaceAsync() + { + using (var session = OpenSession()) + using (session.BeginTransaction()) + { + var cat = await (session.LoadAsync(catId)); + Assert.That(cat, Is.Not.Null); + Assert.That(cat.Name, Is.EqualTo("Bob")); + var proxy = (INHibernateProxy) cat; + Assert.That(proxy.HibernateLazyInitializer.PersistentClass, Is.EqualTo(typeof(Cat))); + } + } + } +} diff --git a/src/NHibernate.Test/NHSpecificTest/GH2067/Fixture.cs b/src/NHibernate.Test/NHSpecificTest/GH2067/Fixture.cs index aac1c4a7828..e0714225f9c 100644 --- a/src/NHibernate.Test/NHSpecificTest/GH2067/Fixture.cs +++ b/src/NHibernate.Test/NHSpecificTest/GH2067/Fixture.cs @@ -48,7 +48,9 @@ protected override void OnTearDown() using (var session = OpenSession()) using (var transaction = session.BeginTransaction()) { - session.CreateQuery("delete from System.Object").ExecuteUpdate(); + // HQL Delete of entities with joins requires temp tables, which are not + // supported by all dialects: use in memory-delete instead. + session.Delete("from System.Object"); transaction.Commit(); } From 0f4f5a55663b591361e4108e09c2a958db2e3106 Mon Sep 17 00:00:00 2001 From: Alexander Zaytsev Date: Wed, 20 Mar 2019 22:41:52 +1300 Subject: [PATCH 6/8] fixup! Fix SQL-ServerCE failures and regen Async. --- .../BaseAndDerivedClassProxiesFixture.cs | 85 ----------------- ...eClassAndDerivedInterfaceProxiesFixture.cs | 93 ------------------- ...ed1InterfaceDerived2ClassProxiesFixture.cs | 89 ------------------ ...eInterfaceAndDerivedClassProxiesFixture.cs | 86 ----------------- .../Async/NHSpecificTest/GH2067/Fixture.cs | 2 +- 5 files changed, 1 insertion(+), 354 deletions(-) delete mode 100644 src/NHibernate.Test/Async/NHSpecificTest/GH2067/BaseAndDerivedClassProxiesFixture.cs delete mode 100644 src/NHibernate.Test/Async/NHSpecificTest/GH2067/BaseClassAndDerivedInterfaceProxiesFixture.cs delete mode 100644 src/NHibernate.Test/Async/NHSpecificTest/GH2067/BaseClassDerived1InterfaceDerived2ClassProxiesFixture.cs delete mode 100644 src/NHibernate.Test/Async/NHSpecificTest/GH2067/BaseInterfaceAndDerivedClassProxiesFixture.cs diff --git a/src/NHibernate.Test/Async/NHSpecificTest/GH2067/BaseAndDerivedClassProxiesFixture.cs b/src/NHibernate.Test/Async/NHSpecificTest/GH2067/BaseAndDerivedClassProxiesFixture.cs deleted file mode 100644 index dab1548dfc5..00000000000 --- a/src/NHibernate.Test/Async/NHSpecificTest/GH2067/BaseAndDerivedClassProxiesFixture.cs +++ /dev/null @@ -1,85 +0,0 @@ -//------------------------------------------------------------------------------ -// -// This code was generated by AsyncGenerator. -// -// Changes to this file may cause incorrect behavior and will be lost if -// the code is regenerated. -// -//------------------------------------------------------------------------------ - - -using System; -using NHibernate.Cfg.MappingSchema; -using NHibernate.Mapping.ByCode; -using NUnit.Framework; - -namespace NHibernate.Test.NHSpecificTest.GH2067 -{ - using System.Threading.Tasks; - namespace BaseAndDerivedClassProxies - { - using System.Threading.Tasks; - - [TestFixture] - public class BaseAndDerivedClassProxiesFixtureAsync : TestCaseMappingByCode - { - private Guid _id = Guid.NewGuid(); - - protected override HbmMapping GetMappings() - { - var mapper = new ModelMapper(); - mapper.Class( - rc => - { - rc.Id(x => x.Id, m => m.Generator(Generators.GuidComb)); - rc.Property(x => x.BaseName); - }); - - mapper.JoinedSubclass( - rc => { rc.Property(x => x.Derived1Name); }); - - mapper.JoinedSubclass( - rc => { rc.Property(x => x.Derived2Name); }); - - return mapper.CompileMappingForAllExplicitlyAddedEntities(); - } - - [Test] - public async Task ProxyForBaseAsync() - { - using (var s = OpenSession()) - { - var b = await (s.LoadAsync(_id)); - Assert.That(b.Id, Is.EqualTo(_id)); - } - } - - [Test] - public async Task ProxyForDerived1Async() - { - using (var s = OpenSession()) - { - var b = await (s.LoadAsync(typeof(Derived1), _id)); - - Assert.That(b, Is.InstanceOf(typeof(Derived1))); - Assert.That(b, Is.InstanceOf(typeof(Base))); - Assert.That(((Derived1) b).Id, Is.EqualTo(_id)); - } - } - - [Test] - public async Task ProxyForDerived2Async() - { - using (var s = OpenSession()) - { - var b = await (s.LoadAsync(typeof(Derived2), _id)); - - Assert.That(b, Is.InstanceOf(typeof(Derived1))); - Assert.That(b, Is.InstanceOf(typeof(Derived2))); - Assert.That(b, Is.InstanceOf(typeof(Base))); - Assert.That(((Derived2) b).Id, Is.EqualTo(_id)); - } - } - } - } -} diff --git a/src/NHibernate.Test/Async/NHSpecificTest/GH2067/BaseClassAndDerivedInterfaceProxiesFixture.cs b/src/NHibernate.Test/Async/NHSpecificTest/GH2067/BaseClassAndDerivedInterfaceProxiesFixture.cs deleted file mode 100644 index f18044468b2..00000000000 --- a/src/NHibernate.Test/Async/NHSpecificTest/GH2067/BaseClassAndDerivedInterfaceProxiesFixture.cs +++ /dev/null @@ -1,93 +0,0 @@ -//------------------------------------------------------------------------------ -// -// This code was generated by AsyncGenerator. -// -// Changes to this file may cause incorrect behavior and will be lost if -// the code is regenerated. -// -//------------------------------------------------------------------------------ - - -using System; -using NHibernate.Cfg.MappingSchema; -using NHibernate.Mapping.ByCode; -using NUnit.Framework; - -namespace NHibernate.Test.NHSpecificTest.GH2067 -{ - using System.Threading.Tasks; - namespace BaseClassAndDerivedInterfaceProxies - { - using System.Threading.Tasks; - - [TestFixture] - public class BaseClassAndDerivedInterfaceProxiesFixtureAsync : TestCaseMappingByCode - { - private Guid _id = Guid.NewGuid(); - - protected override HbmMapping GetMappings() - { - var mapper = new ModelMapper(); - mapper.Class( - rc => - { - rc.Id(x => x.Id, m => m.Generator(Generators.GuidComb)); - rc.Property(x => x.BaseName); - }); - - mapper.JoinedSubclass( - rc => - { - rc.Proxy(typeof(IDerived1)); - rc.Property(x => x.Derived1Name); - }); - - mapper.JoinedSubclass( - rc => - { - rc.Proxy(typeof(IDerived2)); - rc.Property(x => x.Derived2Name); - }); - - return mapper.CompileMappingForAllExplicitlyAddedEntities(); - } - - [Test] - public async Task ProxyForBaseClassAsync() - { - using (var s = OpenSession()) - { - var b = await (s.LoadAsync(_id)); - Assert.That(b.Id, Is.EqualTo(_id)); - } - } - - [Test] - public async Task ProxyForDerived1InterfaceAsync() - { - using (var s = OpenSession()) - { - var b = await (s.LoadAsync(typeof(Derived1Interface), _id)); - - Assert.That(b, Is.InstanceOf(typeof(IDerived1))); -// Assert.That(b, Is.InstanceOf(typeof(Base))); - Assert.That(((IDerived1) b).Id, Is.EqualTo(_id)); - } - } - - [Test] - public async Task ProxyForDerived2InterfaceAsync() - { - using (var s = OpenSession()) - { - var b = await (s.LoadAsync(typeof(Derived2Interface), _id)); - - Assert.That(b, Is.InstanceOf(typeof(IDerived2))); -// Assert.That(b, Is.InstanceOf(typeof(IDerived1))); -// Assert.That(b, Is.InstanceOf(typeof(Base))); - Assert.That(((IDerived2) b).Id, Is.EqualTo(_id)); - } - } - } - } -} diff --git a/src/NHibernate.Test/Async/NHSpecificTest/GH2067/BaseClassDerived1InterfaceDerived2ClassProxiesFixture.cs b/src/NHibernate.Test/Async/NHSpecificTest/GH2067/BaseClassDerived1InterfaceDerived2ClassProxiesFixture.cs deleted file mode 100644 index b06c20b567c..00000000000 --- a/src/NHibernate.Test/Async/NHSpecificTest/GH2067/BaseClassDerived1InterfaceDerived2ClassProxiesFixture.cs +++ /dev/null @@ -1,89 +0,0 @@ -//------------------------------------------------------------------------------ -// -// This code was generated by AsyncGenerator. -// -// Changes to this file may cause incorrect behavior and will be lost if -// the code is regenerated. -// -//------------------------------------------------------------------------------ - - -using System; -using NHibernate.Cfg.MappingSchema; -using NHibernate.Mapping.ByCode; -using NUnit.Framework; - -namespace NHibernate.Test.NHSpecificTest.GH2067 -{ - using System.Threading.Tasks; - namespace BaseClassDerived1InterfaceDerived2ClassProxies - { - using System.Threading.Tasks; - - [TestFixture] - public class BaseClassDerived1InterfaceDerived2ClassProxiesFixtureAsync : TestCaseMappingByCode - { - private Guid _id = Guid.NewGuid(); - - protected override HbmMapping GetMappings() - { - var mapper = new ModelMapper(); - mapper.Class( - rc => - { - rc.Id(x => x.Id, m => m.Generator(Generators.GuidComb)); - rc.Property(x => x.BaseName); - }); - - mapper.JoinedSubclass( - rc => - { - rc.Proxy(typeof(IDerived1)); - rc.Property(x => x.Derived1Name); - }); - - mapper.JoinedSubclass( - rc => { rc.Property(x => x.Derived2Name); }); - - return mapper.CompileMappingForAllExplicitlyAddedEntities(); - } - - [Test] - public async Task ProxyForBaseAsync() - { - using (var s = OpenSession()) - { - var b = await (s.LoadAsync(typeof(Base), _id)); - Assert.That(((Base) b).Id, Is.EqualTo(_id)); - } - } - - [Test] - public async Task ProxyForDerived1InterfaceAsync() - { - using (var s = OpenSession()) - { - var b = await (s.LoadAsync(typeof(Derived1), _id)); - - Assert.That(b, Is.InstanceOf(typeof(IDerived1))); - //Assert.That(b, Is.InstanceOf(typeof(Base))); - Assert.That(((IDerived1) b).Id, Is.EqualTo(_id)); - } - } - - [Test] - public async Task ProxyForDerived2Async() - { - using (var s = OpenSession()) - { - var b = await (s.LoadAsync(typeof(Derived2), _id)); - - Assert.That(b, Is.InstanceOf(typeof(IDerived1))); - Assert.That(b, Is.InstanceOf(typeof(Derived2))); - Assert.That(b, Is.InstanceOf(typeof(Base))); - Assert.That(((Derived2) b).Id, Is.EqualTo(_id)); - } - } - } - } -} diff --git a/src/NHibernate.Test/Async/NHSpecificTest/GH2067/BaseInterfaceAndDerivedClassProxiesFixture.cs b/src/NHibernate.Test/Async/NHSpecificTest/GH2067/BaseInterfaceAndDerivedClassProxiesFixture.cs deleted file mode 100644 index 6e2d1c5aa04..00000000000 --- a/src/NHibernate.Test/Async/NHSpecificTest/GH2067/BaseInterfaceAndDerivedClassProxiesFixture.cs +++ /dev/null @@ -1,86 +0,0 @@ -//------------------------------------------------------------------------------ -// -// This code was generated by AsyncGenerator. -// -// Changes to this file may cause incorrect behavior and will be lost if -// the code is regenerated. -// -//------------------------------------------------------------------------------ - - -using System; -using NHibernate.Cfg.MappingSchema; -using NHibernate.Mapping.ByCode; -using NUnit.Framework; - -namespace NHibernate.Test.NHSpecificTest.GH2067 -{ - using System.Threading.Tasks; - namespace BaseInterfaceAndDerivedClassProxies - { - using System.Threading.Tasks; - - [TestFixture] - public class BaseInterfaceAndDerivedClassProxiesFixtureAsync : TestCaseMappingByCode - { - private Guid _id = Guid.NewGuid(); - - protected override HbmMapping GetMappings() - { - var mapper = new ModelMapper(); - mapper.Class( - rc => - { - rc.Proxy(typeof(IBase)); - rc.Id(x => x.Id, m => m.Generator(Generators.GuidComb)); - rc.Property(x => x.BaseName); - }); - - mapper.JoinedSubclass( - rc => { rc.Property(x => x.Derived1Name); }); - - mapper.JoinedSubclass( - rc => { rc.Property(x => x.Derived2Name); }); - - return mapper.CompileMappingForAllExplicitlyAddedEntities(); - } - - [Test] - public async Task ProxyForBaseAsync() - { - using (var s = OpenSession()) - { - var b = await (s.LoadAsync(typeof(IBase), _id)); - Assert.That(((IBase) b).Id, Is.EqualTo(_id)); - } - } - - [Test] - public async Task ProxyForDerived1Async() - { - using (var s = OpenSession()) - { - var b = await (s.LoadAsync(typeof(Derived1), _id)); - - Assert.That(b, Is.InstanceOf(typeof(Derived1))); - Assert.That(b, Is.InstanceOf(typeof(IBase))); - Assert.That(((Derived1) b).Id, Is.EqualTo(_id)); - } - } - - [Test] - public async Task ProxyForDerived2Async() - { - using (var s = OpenSession()) - { - var b = await (s.LoadAsync(typeof(Derived2), _id)); - - Assert.That(b, Is.InstanceOf(typeof(Derived1))); - Assert.That(b, Is.InstanceOf(typeof(Derived2))); - Assert.That(b, Is.InstanceOf(typeof(IBase))); - Assert.That(((Derived2) b).Id, Is.EqualTo(_id)); - } - } - } - } -} diff --git a/src/NHibernate.Test/Async/NHSpecificTest/GH2067/Fixture.cs b/src/NHibernate.Test/Async/NHSpecificTest/GH2067/Fixture.cs index 42587b26b01..8a7b44db545 100644 --- a/src/NHibernate.Test/Async/NHSpecificTest/GH2067/Fixture.cs +++ b/src/NHibernate.Test/Async/NHSpecificTest/GH2067/Fixture.cs @@ -59,7 +59,7 @@ protected override void OnTearDown() using (var session = OpenSession()) using (var transaction = session.BeginTransaction()) { - // HQL Delete of entities with joins require temp tables, which are not + // HQL Delete of entities with joins requires temp tables, which are not // supported by all dialects: use in memory-delete instead. session.Delete("from System.Object"); From a1fb98a82464febbb881d57b5d4e179ad1243d87 Mon Sep 17 00:00:00 2001 From: Alexander Zaytsev Date: Wed, 20 Mar 2019 22:49:23 +1300 Subject: [PATCH 7/8] fixup! Add IsClassProxy initialization to PostInstantiate --- src/NHibernate/Proxy/AbstractProxyFactory.cs | 1 + src/NHibernate/Proxy/IProxyFactory.cs | 3 ++- src/NHibernate/Proxy/Map/MapProxyFactory.cs | 5 ++++- 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/src/NHibernate/Proxy/AbstractProxyFactory.cs b/src/NHibernate/Proxy/AbstractProxyFactory.cs index 53357329170..b221c8e7a79 100644 --- a/src/NHibernate/Proxy/AbstractProxyFactory.cs +++ b/src/NHibernate/Proxy/AbstractProxyFactory.cs @@ -46,6 +46,7 @@ public virtual void PostInstantiate( IsClassProxy = isClassProxy; } + // Since v5.3 [Obsolete("Override PostInstantiate method with isClassProxy parameter instead.")] public virtual void PostInstantiate( string entityName, diff --git a/src/NHibernate/Proxy/IProxyFactory.cs b/src/NHibernate/Proxy/IProxyFactory.cs index d0cd91189a7..809eb735ea3 100644 --- a/src/NHibernate/Proxy/IProxyFactory.cs +++ b/src/NHibernate/Proxy/IProxyFactory.cs @@ -38,6 +38,7 @@ public interface IProxyFactory /// Essentially equivalent to constructor injection, but contracted /// here via interface. /// + //Since v5.3 [Obsolete("Use ProxyFactoryExtensions.PostInstantiate extension method instead.")] void PostInstantiate(string entityName, System.Type persistentClass, ISet interfaces, MethodInfo getIdentifierMethod, MethodInfo setIdentifierMethod, IAbstractComponentType componentIdType); @@ -51,7 +52,7 @@ void PostInstantiate(string entityName, System.Type persistentClass, ISetIndicates problems generating requested proxy. INHibernateProxy GetProxy(object id, ISessionImplementor session); - // Since 5.3 + // Since v5.3 [Obsolete("Use ProxyFactoryExtensions.GetFieldInterceptionProxy extension method instead.")] object GetFieldInterceptionProxy(object instanceToWrap); } diff --git a/src/NHibernate/Proxy/Map/MapProxyFactory.cs b/src/NHibernate/Proxy/Map/MapProxyFactory.cs index 313f410b649..87fe9dc16f4 100644 --- a/src/NHibernate/Proxy/Map/MapProxyFactory.cs +++ b/src/NHibernate/Proxy/Map/MapProxyFactory.cs @@ -8,8 +8,10 @@ namespace NHibernate.Proxy.Map { public class MapProxyFactory : IProxyFactory { + //6.0 TODO: make readonly private string entityName; + //Since v5.3 [Obsolete("Please use constructor accepting entityName instead.")] public MapProxyFactory() { @@ -20,12 +22,13 @@ public MapProxyFactory(string entityName) this.entityName = entityName; } + //Since v5.3 [Obsolete("Please use constructor accepting entityName instead.")] public void PostInstantiate(string entityName, System.Type persistentClass, ISet interfaces, MethodInfo getIdentifierMethod, MethodInfo setIdentifierMethod, IAbstractComponentType componentIdType) { - //6.0 TODO: throw NotSupportedException + //6.0 TODO: throw NotSupportedException in the new override this.entityName = entityName; } From 5a6722c3e4f752c888352a6378b713d3c64e3639 Mon Sep 17 00:00:00 2001 From: Alexander Zaytsev Date: Sun, 24 Mar 2019 13:32:09 +1300 Subject: [PATCH 8/8] fixup! Add IsClassProxy initialization to PostInstantiate --- src/NHibernate/Proxy/AbstractProxyFactory.cs | 44 ++++++++++--------- .../Tuple/Entity/PocoEntityTuplizer.cs | 6 +-- 2 files changed, 26 insertions(+), 24 deletions(-) diff --git a/src/NHibernate/Proxy/AbstractProxyFactory.cs b/src/NHibernate/Proxy/AbstractProxyFactory.cs index b221c8e7a79..6639010ae46 100644 --- a/src/NHibernate/Proxy/AbstractProxyFactory.cs +++ b/src/NHibernate/Proxy/AbstractProxyFactory.cs @@ -30,19 +30,15 @@ public virtual void PostInstantiate( IAbstractComponentType componentIdType, bool isClassProxy) { - EntityName = entityName; - PersistentClass = persistentClass; - Interfaces = new System.Type[interfaces.Count]; - - if (interfaces.Count > 0) - { - interfaces.CopyTo(Interfaces, 0); - } - - GetIdentifierMethod = getIdentifierMethod; - SetIdentifierMethod = setIdentifierMethod; - ComponentIdType = componentIdType; - OverridesEquals = ReflectHelper.OverridesEquals(persistentClass); +#pragma warning disable 618 + PostInstantiate( + entityName, + persistentClass, + interfaces, + getIdentifierMethod, + setIdentifierMethod, + componentIdType); +#pragma warning restore 618 IsClassProxy = isClassProxy; } @@ -56,14 +52,20 @@ public virtual void PostInstantiate( MethodInfo setIdentifierMethod, IAbstractComponentType componentIdType) { - PostInstantiate( - entityName, - persistentClass, - interfaces, - getIdentifierMethod, - setIdentifierMethod, - componentIdType, - interfaces.Count == 1); + EntityName = entityName; + PersistentClass = persistentClass; + Interfaces = new System.Type[interfaces.Count]; + + if (interfaces.Count > 0) + { + interfaces.CopyTo(Interfaces, 0); + } + + GetIdentifierMethod = getIdentifierMethod; + SetIdentifierMethod = setIdentifierMethod; + ComponentIdType = componentIdType; + OverridesEquals = ReflectHelper.OverridesEquals(persistentClass); + IsClassProxy = interfaces.Count == 1; } public abstract INHibernateProxy GetProxy(object id, ISessionImplementor session); diff --git a/src/NHibernate/Tuple/Entity/PocoEntityTuplizer.cs b/src/NHibernate/Tuple/Entity/PocoEntityTuplizer.cs index e45d74a3edf..aaf9140290e 100644 --- a/src/NHibernate/Tuple/Entity/PocoEntityTuplizer.cs +++ b/src/NHibernate/Tuple/Entity/PocoEntityTuplizer.cs @@ -109,7 +109,7 @@ protected override IInstantiator BuildInstantiator(PersistentClass persistentCla protected override IProxyFactory BuildProxyFactory(PersistentClass persistentClass, IGetter idGetter, ISetter idSetter) { - bool isInterface = false; // NH specific (look the comment below) + bool isInterface = false; // determine the id getter and setter methods from the proxy interface (if any) // determine all interfaces needed by the resulting proxy @@ -124,13 +124,13 @@ protected override IProxyFactory BuildProxyFactory(PersistentClass persistentCla { throw new MappingException("proxy must be either an interface, or the class itself: " + EntityName); } - isInterface = true; // NH (the proxy is an interface all properties can be overridden) + isInterface = true; proxyInterfaces.Add(_proxyInterface); } if (_mappedClass.IsInterface) { - isInterface = true; // NH (the mapped class is an interface all properties can be overridden) + isInterface = true; proxyInterfaces.Add(_mappedClass); }