From: <dav...@us...> - 2008-12-28 22:21:02
|
Revision: 3967 http://nhibernate.svn.sourceforge.net/nhibernate/?rev=3967&view=rev Author: davybrion Date: 2008-12-28 22:20:58 +0000 (Sun, 28 Dec 2008) Log Message: ----------- Modified Paths: -------------- trunk/nhibernate/src/NHibernate/Proxy/Poco/BasicLazyInitializer.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/NH1549/ trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1549/CategoryWithInheritedId.cs trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1549/EntityInt32.cs trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1549/Fixture.cs trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1549/Mappings.hbm.xml trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1549/ProductWithInheritedId.cs Modified: trunk/nhibernate/src/NHibernate/Proxy/Poco/BasicLazyInitializer.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Proxy/Poco/BasicLazyInitializer.cs 2008-12-27 19:53:57 UTC (rev 3966) +++ trunk/nhibernate/src/NHibernate/Proxy/Poco/BasicLazyInitializer.cs 2008-12-28 22:20:58 UTC (rev 3967) @@ -62,7 +62,7 @@ /// underlying proxied object is needed then it returns the result <see cref="AbstractLazyInitializer.InvokeImplementation"/> /// which indicates that the Proxy will need to forward to the real implementation. /// </returns> - public virtual object Invoke(MethodBase method, object[] args, object proxy) + public virtual object Invoke(MethodInfo method, object[] args, object proxy) { string methodName = method.Name; int paramCount = method.GetParameters().Length; @@ -73,7 +73,7 @@ { return IdentityEqualityComparer.GetHashCode(proxy); } - else if (IsUninitialized && method.Equals(getIdentifierMethod)) + else if (IsUninitialized && IsEqualToIdentifierMethod(method)) { return Identifier; } @@ -135,5 +135,18 @@ return InvokeImplementation; } + private bool IsEqualToIdentifierMethod(MethodInfo method) + { + if (getIdentifierMethod != null) + { + // in the case of inherited identifier methods (from a base class or an iterface) the + // passed in MethodBase object is not equal to the getIdentifierMethod instance that we + // have... but if their names and return types are identical, then it is the correct + // identifier method + return method.Name.Equals(getIdentifierMethod.Name) && method.ReturnType.Equals(getIdentifierMethod.ReturnType); + } + + return false; + } } } Modified: trunk/nhibernate/src/NHibernate/Util/ReflectHelper.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Util/ReflectHelper.cs 2008-12-27 19:53:57 UTC (rev 3966) +++ trunk/nhibernate/src/NHibernate/Util/ReflectHelper.cs 2008-12-28 22:20:58 UTC (rev 3967) @@ -19,7 +19,7 @@ private static readonly ILog log = LogManager.GetLogger(typeof(ReflectHelper)); public static BindingFlags AnyVisibilityInstance = BindingFlags.Instance | BindingFlags.Public | - BindingFlags.NonPublic; + BindingFlags.NonPublic; private ReflectHelper() { @@ -29,7 +29,7 @@ private static System.Type[] NoClasses = System.Type.EmptyTypes; private static readonly MethodInfo Exception_InternalPreserveStackTrace = - typeof (Exception).GetMethod("InternalPreserveStackTrace", BindingFlags.Instance | BindingFlags.NonPublic); + typeof(Exception).GetMethod("InternalPreserveStackTrace", BindingFlags.Instance | BindingFlags.NonPublic); /// <summary> /// Determine if the specified <see cref="System.Type"/> overrides the @@ -41,7 +41,7 @@ { try { - MethodInfo equals = clazz.GetMethod("Equals", new System.Type[] {typeof(object)}); + MethodInfo equals = clazz.GetMethod("Equals", new System.Type[] { typeof(object) }); if (equals == null) { return false; @@ -127,7 +127,7 @@ System.Type heuristicClass = propertyClass; if (propertyClass.IsGenericType - && propertyClass.GetGenericTypeDefinition().Equals(typeof(Nullable<>))) + && propertyClass.GetGenericTypeDefinition().Equals(typeof(Nullable<>))) { heuristicClass = propertyClass.GetGenericArguments()[0]; } @@ -292,15 +292,15 @@ public static bool TryLoadAssembly(string assemblyName) { - if(string.IsNullOrEmpty(assemblyName)) + if (string.IsNullOrEmpty(assemblyName)) return false; - bool result= true; + bool result = true; try { Assembly.Load(assemblyName); } - catch(Exception) + catch (Exception) { result = false; } @@ -446,7 +446,7 @@ /// <returns>The unwrapped exception.</returns> public static Exception UnwrapTargetInvocationException(TargetInvocationException ex) { - Exception_InternalPreserveStackTrace.Invoke(ex.InnerException, new Object[] {}); + Exception_InternalPreserveStackTrace.Invoke(ex.InnerException, new Object[] { }); return ex.InnerException; } @@ -472,14 +472,7 @@ } System.Type[] tps = GetMethodSignature(method); - try - { - return type.GetMethod(method.Name, defaultBindingFlags, null, tps, null); - } - catch (Exception) - { - return null; - } + return SafeGetMethod(type, method, tps); } /// <summary> @@ -493,6 +486,8 @@ /// </remarks> public static MethodInfo TryGetMethod(IEnumerable<System.Type> types, MethodInfo method) { + var bindingFlags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic; + // This method will be used when we support multiple proxy interfaces. if (types == null) { @@ -505,21 +500,16 @@ System.Type[] tps = GetMethodSignature(method); MethodInfo result = null; + foreach (var type in types) { - try + result = SafeGetMethod(type, method, tps); + if (result != null) { - result = type.GetMethod(method.Name, defaultBindingFlags, null, tps, null); - if (result != null) - { - return result; - } + return result; } - catch (Exception) - { - return null; - } } + return result; } @@ -533,5 +523,19 @@ } return tps; } + + private static MethodInfo SafeGetMethod(System.Type type, MethodInfo method, System.Type[] tps) + { + var bindingFlags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic; + + try + { + return type.GetMethod(method.Name, bindingFlags, null, tps, null); + } + catch (Exception) + { + return null; + } + } } } Added: trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1549/CategoryWithInheritedId.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1549/CategoryWithInheritedId.cs (rev 0) +++ trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1549/CategoryWithInheritedId.cs 2008-12-28 22:20:58 UTC (rev 3967) @@ -0,0 +1,15 @@ +using System; + +namespace NHibernate.Test.NHSpecificTest.NH1549 +{ + public class CategoryWithInheritedId : EntityInt32 + { + public virtual string Name { get; set; } + } + + public class CategoryWithId + { + public virtual int Id { get; set; } + public virtual string Name { get; set; } + } +} \ No newline at end of file Property changes on: trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1549/CategoryWithInheritedId.cs ___________________________________________________________________ Added: svn:mergeinfo + Added: trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1549/EntityInt32.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1549/EntityInt32.cs (rev 0) +++ trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1549/EntityInt32.cs 2008-12-28 22:20:58 UTC (rev 3967) @@ -0,0 +1,7 @@ +namespace NHibernate.Test.NHSpecificTest.NH1549 +{ + public abstract class EntityInt32 + { + public virtual int Id { get; set; } + } +} \ No newline at end of file Added: trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1549/Fixture.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1549/Fixture.cs (rev 0) +++ trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1549/Fixture.cs 2008-12-28 22:20:58 UTC (rev 3967) @@ -0,0 +1,93 @@ +using NUnit.Framework; + +namespace NHibernate.Test.NHSpecificTest.NH1549 +{ + [TestFixture] + public class Fixture : BugTestCase + { + /// <summary> + /// Verifies that an entity with a base class containing the id property + /// can have the id accessed without loading the entity + /// </summary> + [Test] + public void CanLoadForEntitiesWithInheritedIds() + { + //create some related products + var category = new CategoryWithInheritedId {Name = "Fruit"}; + var product = new ProductWithInheritedId {CategoryWithInheritedId = category}; + + using (ISession session = OpenSession()) + { + using (ITransaction trans = session.BeginTransaction()) + { + session.Save(category); + session.Save(product); + trans.Commit(); + } + } + + ProductWithInheritedId restoredProductWithInheritedId; + + //restore the product from the db in another session so that + //the association is a proxy + using (ISession session = OpenSession()) + { + restoredProductWithInheritedId = session.Get<ProductWithInheritedId>(product.Id); + } + + //verify that the category is a proxy + Assert.IsFalse(NHibernateUtil.IsInitialized(restoredProductWithInheritedId.CategoryWithInheritedId)); + + //we should be able to access the id of the category outside of the session + Assert.AreEqual(category.Id, restoredProductWithInheritedId.CategoryWithInheritedId.Id); + } + + [Test] + public void CanLoadForEntitiesWithTheirOwnIds() + { + //create some related products + var category = new CategoryWithId { Name = "Fruit" }; + var product = new ProductWithId { CategoryWithId = category }; + + using (ISession session = OpenSession()) + { + using (ITransaction trans = session.BeginTransaction()) + { + session.Save(category); + session.Save(product); + trans.Commit(); + } + } + + ProductWithId restoredProductWithInheritedId; + + //restore the product from the db in another session so that + //the association is a proxy + using (ISession session = OpenSession()) + { + restoredProductWithInheritedId = session.Get<ProductWithId>(product.Id); + } + + //verify that the category is a proxy + Assert.IsFalse(NHibernateUtil.IsInitialized(restoredProductWithInheritedId.CategoryWithId)); + + //we should be able to access the id of the category outside of the session + Assert.AreEqual(category.Id, restoredProductWithInheritedId.CategoryWithId.Id); + } + + protected override void OnTearDown() + { + using (ISession session = OpenSession()) { + + using (ITransaction trans = session.BeginTransaction()) + { + session.Delete("from ProductWithId"); + session.Delete("from CategoryWithId"); + session.Delete("from ProductWithInheritedId"); + session.Delete("from CategoryWithInheritedId"); + trans.Commit(); + } + } + } + } +} \ No newline at end of file Added: trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1549/Mappings.hbm.xml =================================================================== --- trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1549/Mappings.hbm.xml (rev 0) +++ trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1549/Mappings.hbm.xml 2008-12-28 22:20:58 UTC (rev 3967) @@ -0,0 +1,35 @@ +<?xml version="1.0" encoding="utf-8" ?> +<hibernate-mapping + xmlns="urn:nhibernate-mapping-2.2" + namespace="NHibernate.Test.NHSpecificTest.NH1549" + assembly="NHibernate.Test"> + + <class name="CategoryWithInheritedId"> + <id name="Id" type="System.Int32"> + <generator class="native" /> + </id> + <property name="Name" /> + </class> + + <class name="ProductWithInheritedId" lazy="false"> + <id name="Id" type="System.Int32"> + <generator class="native" /> + </id> + <many-to-one name="CategoryWithInheritedId"/> + </class> + + <class name="CategoryWithId"> + <id name="Id" type="System.Int32"> + <generator class="native" /> + </id> + <property name="Name" /> + </class> + + <class name="ProductWithId" lazy="false"> + <id name="Id" type="System.Int32"> + <generator class="native" /> + </id> + <many-to-one name="CategoryWithId"/> + </class> + +</hibernate-mapping> Added: trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1549/ProductWithInheritedId.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1549/ProductWithInheritedId.cs (rev 0) +++ trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1549/ProductWithInheritedId.cs 2008-12-28 22:20:58 UTC (rev 3967) @@ -0,0 +1,15 @@ +using System; + +namespace NHibernate.Test.NHSpecificTest.NH1549 +{ + public class ProductWithInheritedId : EntityInt32 + { + public CategoryWithInheritedId CategoryWithInheritedId { get; set; } + } + + public class ProductWithId + { + public virtual int Id { get; set; } + public CategoryWithId CategoryWithId { get; set; } + } +} \ No newline at end of file Property changes on: trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1549/ProductWithInheritedId.cs ___________________________________________________________________ Added: svn:mergeinfo + Modified: trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj =================================================================== --- trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj 2008-12-27 19:53:57 UTC (rev 3966) +++ trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj 2008-12-28 22:20:58 UTC (rev 3967) @@ -378,6 +378,10 @@ <Compile Include="NHSpecificTest\NH1274ExportExclude\Person.cs" /> <Compile Include="NHSpecificTest\NH1443\Fixture.cs" /> <Compile Include="NHSpecificTest\NH1521\Fixture.cs" /> + <Compile Include="NHSpecificTest\NH1549\CategoryWithInheritedId.cs" /> + <Compile Include="NHSpecificTest\NH1549\EntityInt32.cs" /> + <Compile Include="NHSpecificTest\NH1549\Fixture.cs" /> + <Compile Include="NHSpecificTest\NH1549\ProductWithInheritedId.cs" /> <Compile Include="NHSpecificTest\NH1605\Fixture.cs" /> <Compile Include="NHSpecificTest\NH1609\Entities.cs" /> <Compile Include="NHSpecificTest\NH1609\Fixture.cs" /> @@ -1577,6 +1581,7 @@ <EmbeddedResource Include="Cascade\JobBatch.hbm.xml" /> <EmbeddedResource Include="Deletetransient\Person.hbm.xml" /> <Content Include="DynamicEntity\package.html" /> + <EmbeddedResource Include="NHSpecificTest\NH1549\Mappings.hbm.xml" /> <EmbeddedResource Include="NHSpecificTest\NH1521\AclassWithSpecific.hbm.xml" /> <EmbeddedResource Include="NHSpecificTest\NH1521\AclassWithNothing.hbm.xml" /> <EmbeddedResource Include="NHSpecificTest\NH1521\AclassWithDefault.hbm.xml" /> Modified: trunk/nhibernate/src/NHibernate.Test/UtilityTest/ReflectHelperFixture.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Test/UtilityTest/ReflectHelperFixture.cs 2008-12-27 19:53:57 UTC (rev 3966) +++ trunk/nhibernate/src/NHibernate.Test/UtilityTest/ReflectHelperFixture.cs 2008-12-28 22:20:58 UTC (rev 3967) @@ -56,11 +56,13 @@ [Test] public void TryGetMethod() { - const BindingFlags bf = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.DeclaredOnly; - MethodInfo mig = typeof (MyBaseImplementation).GetMethod("get_Id", bf); + //const BindingFlags bf = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.DeclaredOnly; + const BindingFlags bf = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic; + 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); @@ -78,6 +80,20 @@ 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); + + MethodInfo mdig = typeof(MyDerivedImplementation).GetMethod("get_Id", bf); + MethodInfo mdis = typeof(MyDerivedImplementation).GetMethod("set_Id", bf); + MethodInfo mdng = typeof(MyDerivedImplementation).GetMethod("get_Name", bf); + MethodInfo mdns = typeof(MyDerivedImplementation).GetMethod("set_Name", bf); + MethodInfo mddg = typeof(MyDerivedImplementation).GetMethod("get_Description", bf); + MethodInfo mdds = typeof(MyDerivedImplementation).GetMethod("set_Description", bf); + + Assert.That(ReflectHelper.TryGetMethod(new[] { typeof(IMyBaseInterface), typeof(IMyInterface) }, mdig), Is.Not.Null); + Assert.That(ReflectHelper.TryGetMethod(new[] { typeof(IMyBaseInterface), typeof(IMyInterface) }, mdis), Is.Null); + Assert.That(ReflectHelper.TryGetMethod(new[] { typeof(IMyBaseInterface), typeof(IMyInterface) }, mdng), Is.Not.Null); + Assert.That(ReflectHelper.TryGetMethod(new[] { typeof(IMyBaseInterface), typeof(IMyInterface) }, mdns), Is.Not.Null); + Assert.That(ReflectHelper.TryGetMethod(new[] { typeof(IMyBaseInterface), typeof(IMyInterface) }, mddg), Is.Not.Null); + Assert.That(ReflectHelper.TryGetMethod(new[] { typeof(IMyBaseInterface), typeof(IMyInterface) }, mdds), Is.Null); } } @@ -115,11 +131,15 @@ public string Name { get; set; } } + public class MyDerivedImplementation : MyBaseImplementation, IMyInterface + { + public string Description { 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. |