From: <fab...@us...> - 2008-10-18 22:18:25
|
Revision: 3865 http://nhibernate.svn.sourceforge.net/nhibernate/?rev=3865&view=rev Author: fabiomaulo Date: 2008-10-18 22:18:15 +0000 (Sat, 18 Oct 2008) Log Message: ----------- - Fix NH-1495 and NH-1083 Modified Paths: -------------- trunk/nhibernate/src/NHibernate/Tuple/Entity/AbstractEntityTuplizer.cs trunk/nhibernate/src/NHibernate/Tuple/Entity/PocoEntityTuplizer.cs trunk/nhibernate/src/NHibernate/Util/ReflectHelper.cs trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj trunk/nhibernate/src/NHibernate.Test/UtilityTest/ReflectHelperFixture.cs Added Paths: ----------- trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1495/ trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1495/Fixture.cs trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1495/Mappings.hbm.xml trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1495/Person.cs Modified: trunk/nhibernate/src/NHibernate/Tuple/Entity/AbstractEntityTuplizer.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Tuple/Entity/AbstractEntityTuplizer.cs 2008-10-18 04:06:39 UTC (rev 3864) +++ trunk/nhibernate/src/NHibernate/Tuple/Entity/AbstractEntityTuplizer.cs 2008-10-18 22:18:15 UTC (rev 3865) @@ -71,20 +71,7 @@ if (entityMetamodel.IsLazy) { - /* NH Different implementation - * When we are using an interface we need to use the interface itself to have - * the getter and setter of the identifier to prevent proxy initialization. - * The BasicLazyInitializer use method.Equals to recognize the the identifier setter. - */ - IGetter pidGetter = idGetter; - ISetter pidSetter = idSetter; - if (mappingInfo.HasIdentifierProperty && mappingInfo.ProxyInterface != null) - { - pidGetter = mappingInfo.IdentifierProperty.GetGetter(mappingInfo.ProxyInterface); - pidSetter = mappingInfo.IdentifierProperty.GetSetter(mappingInfo.ProxyInterface); - } - proxyFactory = BuildProxyFactory(mappingInfo, pidGetter, pidSetter); - /*******************************************************************************/ + proxyFactory = BuildProxyFactory(mappingInfo, idGetter, idSetter); if (proxyFactory == null) { entityMetamodel.IsLazy = false; Modified: trunk/nhibernate/src/NHibernate/Tuple/Entity/PocoEntityTuplizer.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Tuple/Entity/PocoEntityTuplizer.cs 2008-10-18 04:06:39 UTC (rev 3864) +++ trunk/nhibernate/src/NHibernate/Tuple/Entity/PocoEntityTuplizer.cs 2008-10-18 22:18:15 UTC (rev 3865) @@ -10,6 +10,7 @@ using NHibernate.Properties; using NHibernate.Proxy; using NHibernate.Type; +using NHibernate.Util; namespace NHibernate.Tuple.Entity { @@ -144,13 +145,11 @@ MethodInfo idGetterMethod = idGetter == null ? null : idGetter.Method; MethodInfo idSetterMethod = idSetter == null ? null : idSetter.Method; - MethodInfo proxyGetIdentifierMethod = idGetterMethod == null || _proxyInterface == null ? null : - idGetterMethod; - // TODO H3.2 different behaviour ReflectHelper.GetMethod(_proxyInterface, idGetterMethod); + MethodInfo proxyGetIdentifierMethod = idGetterMethod == null || _proxyInterface == null ? null : + ReflectHelper.TryGetMethod(_proxyInterface, idGetterMethod); - MethodInfo proxySetIdentifierMethod = idSetterMethod == null || _proxyInterface == null ? null : - idSetterMethod; - // TODO H3.2 different behaviour ReflectHelper.GetMethod(_proxyInterface, idSetterMethod); + MethodInfo proxySetIdentifierMethod = idSetterMethod == null || _proxyInterface == null ? null : + ReflectHelper.TryGetMethod(_proxyInterface, idSetterMethod); IProxyFactory pf = BuildProxyFactoryInternal(persistentClass, idGetter, idSetter); try Modified: trunk/nhibernate/src/NHibernate/Util/ReflectHelper.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Util/ReflectHelper.cs 2008-10-18 04:06:39 UTC (rev 3864) +++ trunk/nhibernate/src/NHibernate/Util/ReflectHelper.cs 2008-10-18 22:18:15 UTC (rev 3865) @@ -1,4 +1,5 @@ using System; +using System.Collections.Generic; using System.Reflection; using System.Text; using log4net; @@ -12,6 +13,9 @@ /// </summary> public sealed class ReflectHelper { + private const BindingFlags defaultBindingFlags = + BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.DeclaredOnly; + private static readonly ILog log = LogManager.GetLogger(typeof(ReflectHelper)); public static BindingFlags AnyVisibilityInstance = BindingFlags.Instance | BindingFlags.Public | @@ -445,5 +449,89 @@ Exception_InternalPreserveStackTrace.Invoke(ex.InnerException, new Object[] {}); return ex.InnerException; } + + /// <summary> + /// Try to find a method in a given type. + /// </summary> + /// <param name="type">The given type.</param> + /// <param name="method">The method info.</param> + /// <returns>The found method or null.</returns> + /// <remarks> + /// The <paramref name="method"/>, in general, become from another <see cref="Type"/>. + /// </remarks> + public static MethodInfo TryGetMethod(System.Type type, MethodInfo method) + { + if (type == null) + { + throw new ArgumentNullException("type"); + } + + if (method == null) + { + return null; + } + + System.Type[] tps = GetMethodSignature(method); + try + { + return type.GetMethod(method.Name, defaultBindingFlags, null, tps, null); + } + catch (Exception) + { + return null; + } + } + + /// <summary> + /// Try to find a method in a serie of given types. + /// </summary> + /// <param name="types">The serie of types where find.</param> + /// <param name="method">The method info.</param> + /// <returns>The found method or null.</returns> + /// <remarks> + /// The <paramref name="method"/>, in general, become from another <see cref="Type"/>. + /// </remarks> + public static MethodInfo TryGetMethod(IEnumerable<System.Type> types, MethodInfo method) + { + // This method will be used when we support multiple proxy interfaces. + if (types == null) + { + throw new ArgumentNullException("types"); + } + if (method == null) + { + return null; + } + + System.Type[] tps = GetMethodSignature(method); + MethodInfo result = null; + foreach (var type in types) + { + try + { + result = type.GetMethod(method.Name, defaultBindingFlags, null, tps, null); + if (result != null) + { + return result; + } + } + catch (Exception) + { + return null; + } + } + return result; + } + + private static System.Type[] GetMethodSignature(MethodInfo method) + { + var pi = method.GetParameters(); + var tps = new System.Type[pi.Length]; + for (int i = 0; i < pi.Length; i++) + { + tps[i] = pi[i].ParameterType; + } + return tps; + } } } Added: trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1495/Fixture.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1495/Fixture.cs (rev 0) +++ trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1495/Fixture.cs 2008-10-18 22:18:15 UTC (rev 3865) @@ -0,0 +1,42 @@ +using NUnit.Framework; + +namespace NHibernate.Test.NHSpecificTest.NH1495 +{ + [TestFixture] + public class Fixture : BugTestCase + { + [Test] + public void CreateTest() + { + object id; + + using (ISession session = OpenSession()) + { + var person = new Person {Name = "Nelo"}; + + using (ITransaction trans = session.BeginTransaction()) + { + session.Save(person); + trans.Commit(); + } + + id = person.Id; + } + + using (ISession session = OpenSession()) + { + var person = (IPerson)session.Load(typeof(Person), id); //to work with the proxy + + Assert.IsNotNull(person); + Assert.AreEqual("Nelo", person.Name); + + using (ITransaction trans = session.BeginTransaction()) + { + session.Delete(person); + trans.Commit(); + } + } + } + + } +} \ No newline at end of file Added: trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1495/Mappings.hbm.xml =================================================================== --- trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1495/Mappings.hbm.xml (rev 0) +++ trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1495/Mappings.hbm.xml 2008-10-18 22:18:15 UTC (rev 3865) @@ -0,0 +1,12 @@ +<?xml version="1.0" encoding="utf-8" ?> +<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" + assembly="NHibernate.Test" + namespace="NHibernate.Test.NHSpecificTest.NH1495"> + + <class name="Person" proxy="IPerson"> + <id name="Id" type="Int64" access="backfield"> + <generator class="hilo" /> + </id> + <property name="Name" /> + </class> +</hibernate-mapping> Added: trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1495/Person.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1495/Person.cs (rev 0) +++ trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1495/Person.cs 2008-10-18 22:18:15 UTC (rev 3865) @@ -0,0 +1,15 @@ +namespace NHibernate.Test.NHSpecificTest.NH1495 +{ + public interface IPerson + { + object Id { get;} + string Name { get; set; } + } + + public class Person : IPerson + { + public object Id { get; private set; } + + public string Name { get; set; } + } +} \ No newline at end of file Modified: trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj =================================================================== --- trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj 2008-10-18 04:06:39 UTC (rev 3864) +++ trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj 2008-10-18 22:18:15 UTC (rev 3865) @@ -502,6 +502,8 @@ <Compile Include="NHSpecificTest\NH1492\ChildEntity.cs" /> <Compile Include="NHSpecificTest\NH1492\Entity.cs" /> <Compile Include="NHSpecificTest\NH1492\Fixture.cs" /> + <Compile Include="NHSpecificTest\NH1495\Person.cs" /> + <Compile Include="NHSpecificTest\NH1495\Fixture.cs" /> <Compile Include="NHSpecificTest\NH1499\Document.cs" /> <Compile Include="NHSpecificTest\NH1499\Fixture.cs" /> <Compile Include="NHSpecificTest\NH1499\Person.cs" /> @@ -1503,6 +1505,7 @@ <EmbeddedResource Include="Cascade\JobBatch.hbm.xml" /> <EmbeddedResource Include="Deletetransient\Person.hbm.xml" /> <Content Include="DynamicEntity\package.html" /> + <EmbeddedResource Include="NHSpecificTest\NH1495\Mappings.hbm.xml" /> <EmbeddedResource Include="ProjectionFixtures\Mapping.hbm.xml" /> <EmbeddedResource Include="NHSpecificTest\NH1033\Mappings.hbm.xml" /> <EmbeddedResource Include="EntityModeTest\Multi\Stock.hbm.xml" /> Modified: trunk/nhibernate/src/NHibernate.Test/UtilityTest/ReflectHelperFixture.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Test/UtilityTest/ReflectHelperFixture.cs 2008-10-18 04:06:39 UTC (rev 3864) +++ trunk/nhibernate/src/NHibernate.Test/UtilityTest/ReflectHelperFixture.cs 2008-10-18 22:18:15 UTC (rev 3865) @@ -1,7 +1,9 @@ using System; +using System.Reflection; using NHibernate.DomainModel; using NHibernate.Util; using NUnit.Framework; +using NUnit.Framework.SyntaxHelpers; namespace NHibernate.Test.UtilityTest { @@ -50,6 +52,33 @@ System.Type int32 = ReflectHelper.ClassForName("System.Int32"); Assert.AreEqual(typeof(Int32), int32); } + + [Test] + public void TryGetMethod() + { + const BindingFlags bf = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.DeclaredOnly; + MethodInfo mig = typeof (MyBaseImplementation).GetMethod("get_Id", bf); + MethodInfo mis = typeof(MyBaseImplementation).GetMethod("set_Id", bf); + MethodInfo mng = typeof(MyBaseImplementation).GetMethod("get_Name", bf); + MethodInfo mns = typeof(MyBaseImplementation).GetMethod("set_Name", bf); + Assert.That(ReflectHelper.TryGetMethod(typeof(IMyBaseInterface), mig), Is.Not.Null); + Assert.That(ReflectHelper.TryGetMethod(typeof(IMyBaseInterface), mis), Is.Null); + Assert.That(ReflectHelper.TryGetMethod(typeof(IMyBaseInterface), mng), Is.Not.Null); + Assert.That(ReflectHelper.TryGetMethod(typeof(IMyBaseInterface), mns), Is.Not.Null); + + mig = typeof(MyImplementation).GetMethod("get_Id", bf); + mis = typeof(MyImplementation).GetMethod("set_Id", bf); + mng = typeof(MyImplementation).GetMethod("get_Name", bf); + mns = typeof(MyImplementation).GetMethod("set_Name", bf); + MethodInfo mdg = typeof(MyImplementation).GetMethod("get_Description", bf); + MethodInfo mds = typeof(MyImplementation).GetMethod("set_Description", bf); + Assert.That(ReflectHelper.TryGetMethod(new[] { typeof(IMyBaseInterface), typeof(IMyInterface) }, mig), Is.Not.Null); + Assert.That(ReflectHelper.TryGetMethod(new[] { typeof(IMyBaseInterface), typeof(IMyInterface) }, mis), Is.Null); + Assert.That(ReflectHelper.TryGetMethod(new[] { typeof(IMyBaseInterface), typeof(IMyInterface) }, mng), Is.Not.Null); + Assert.That(ReflectHelper.TryGetMethod(new[] { typeof(IMyBaseInterface), typeof(IMyInterface) }, mns), Is.Not.Null); + Assert.That(ReflectHelper.TryGetMethod(new[] { typeof(IMyBaseInterface), typeof(IMyInterface) }, mdg), Is.Not.Null); + Assert.That(ReflectHelper.TryGetMethod(new[] { typeof(IMyBaseInterface), typeof(IMyInterface) }, mds), Is.Null); + } } public class ARhf @@ -68,4 +97,29 @@ public class BRhf : ARhf { } + + public interface IMyBaseInterface + { + int Id { get; } + string Name { get; set; } + } + + public interface IMyInterface: IMyBaseInterface + { + string Description { get; } + } + + public class MyBaseImplementation : IMyBaseInterface + { + public int Id { get; set; } + public string Name { get; set; } + } + + public class MyImplementation: IMyInterface + { + public int Id{ get; set; } + public string Name { get; set; } + public string Description { get; set; } + } + } \ No newline at end of file This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |