You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@ibatis.apache.org by "Thomas Tannahill (JIRA)" <ib...@incubator.apache.org> on 2005/10/11 22:59:05 UTC

[jira] Created: (IBATISNET-118) CacheKey.Equals(object) override can return true when the parameters have the same HashCode but are not equal.

CacheKey.Equals(object) override can return true when the parameters have the same HashCode but are not equal.
--------------------------------------------------------------------------------------------------------------

         Key: IBATISNET-118
         URL: http://issues.apache.org/jira/browse/IBATISNET-118
     Project: iBatis for .NET
        Type: Bug
  Components: DataMapper  
    Versions: DataMapper 1.2.1    
 Environment: Windows
    Reporter: Thomas Tannahill


CacheKey.Equals(object) override can return true when the parameters have the same HashCode but are not equal.  This can cause false cache hits.

Only an issue for complex parameters.

Failing NUnit test:

---- UNIT TEST BEGIN ----
using IBatisNet.DataMapper;
using IBatisNet.DataMapper.TypeHandlers;
using NUnit.Framework;

namespace IBatisNet.DataAccess
{
	[TestFixture]
	public class CacheKeyTests
	{
		private const long A_LONG = 1L;
		private const long ANOTHER_LONG_WITH_SAME_HASHCODE = -9223372034707292159;
		
		public CacheKeyTests()
		{
		}

		[Test]
		public void ShouldNotBeConsideredEqualWhenParametersHaveTheSameHashCodeButAreNotEqual()
		{
			TypeHandlerFactory factory = new TypeHandlerFactory(); 

			// Two cache keys are equal except for the parameter.
			CacheKey key = new CacheKey(factory, "STATEMENT", "SQL", new TestClass(A_LONG), new string[] {"AProperty"}, 0, 0, CacheKeyType.Object);
			CacheKey aDifferentKey = new CacheKey(factory, "STATEMENT", "SQL", new TestClass(ANOTHER_LONG_WITH_SAME_HASHCODE), new string[] {"AProperty"}, 0, 0, CacheKeyType.Object);

			Assert.IsFalse(aDifferentKey.Equals(key)); // should not be equal.
		}
	}

	public class TestClass
	{
		private long aProperty;

		public TestClass(long aProperty)
		{
			this.aProperty = aProperty;
		}

		public long AProperty
		{
			get { return aProperty; }
			set { aProperty = value; }
		}
	}
}
---- UNIT TEST END ----

The test passes if you replace this line in CacheKey.Equals():

               if (_hashCode != cacheKey._hashCode) return false;

with something like this:

               if (this._parameter == null && cacheKey._parameter != null) return false;
               if (this._parameter != null && cacheKey._parameter == null) return false;
               if (!this._parameter.Equals(cacheKey._parameter)) return false;


-- 
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators:
   http://issues.apache.org/jira/secure/Administrators.jspa
-
For more information on JIRA, see:
   http://www.atlassian.com/software/jira


Re: [jira] Commented: (IBATISNET-118) CacheKey.Equals(object) override can return true when the parameters have the same HashCode but are not equal.

Posted by Clinton Begin <cl...@gmail.com>.
The iBATIS for Java version compares the parameters using the same values
that are sent to the database, which means all values compared are primitive
(with equals and hashcode consistently implemented by the core class
library).

Something similar could be done in the .NET version.  Like I said, this is
kind of a "been there, done that" for me, as we had the same issue in the
Java version.

Thomas Tannahill has already written a test that fails and an implementation
that fixes it.  I'll ask him for it.

Cheers,
Clinton


On 11/30/05, Jeremy Gray (JIRA) <ib...@incubator.apache.org> wrote:
>
>     [
> http://issues.apache.org/jira/browse/IBATISNET-118?page=comments#action_12358975]
>
> Jeremy Gray commented on IBATISNET-118:
> ---------------------------------------
>
> Gilles: Having reviewed the CacheKey code _again_ this fall (after first
> looking at it back in the spring) I can tell you that it does not do what
> you describe. Types that need to be treated as special cases (e.g.
> Hashtable) given the needs of the application are currently using only
> hashcode and perhaps Equals comparisons. Other types are treated as a
> special case (walking their properties) when the .NET equality semantics
> demand that they strictly be compared based on GetHashCode and Equals. Even
> given the current logic, GetHashCode and Equals are not internally
> consistent - one of them applies different special cases than the other.
>
> Clinton: Our company would love it to be fixed for us :), but will be
> happy to implement the fix at the point in our schedule where it becomes
> critical. That said, at the time we can implement it I doubt we'll be able
> to verify against the full set of ibatis.net test cases, so we might need
> a hand in verification from someone who is already set up to do so.
>
> > CacheKey.Equals(object) override can return true when the parameters
> have the same HashCode but are not equal.
> >
> --------------------------------------------------------------------------------------------------------------
> >
> >          Key: IBATISNET-118
> >          URL: http://issues.apache.org/jira/browse/IBATISNET-118
> >      Project: iBatis for .NET
> >         Type: Bug
> >   Components: DataMapper
> >     Versions: DataMapper 1.2.1
> >  Environment: Windows
> >     Reporter: Thomas Tannahill
> >     Assignee: Gilles Bayon
> >      Fix For: DataMapper 1.3
>
> >
> > CacheKey.Equals(object) override can return true when the parameters
> have the same HashCode but are not equal.  This can cause false cache hits.
> > Only an issue for complex parameters.
> > Failing NUnit test:
> > ---- UNIT TEST BEGIN ----
> > using IBatisNet.DataMapper;
> > using IBatisNet.DataMapper.TypeHandlers;
> > using NUnit.Framework;
> > namespace IBatisNet.DataAccess
> > {
> >       [TestFixture]
> >       public class CacheKeyTests
> >       {
> >               private const long A_LONG = 1L;
> >               private const long ANOTHER_LONG_WITH_SAME_HASHCODE =
> -9223372034707292159;
> >
> >               public CacheKeyTests()
> >               {
> >               }
> >               [Test]
> >               public void
> ShouldNotBeConsideredEqualWhenParametersHaveTheSameHashCodeButAreNotEqual()
> >               {
> >                       TypeHandlerFactory factory = new
> TypeHandlerFactory();
> >                       // Two cache keys are equal except for the
> parameter.
> >                       CacheKey key = new CacheKey(factory, "STATEMENT",
> "SQL", new TestClass(A_LONG), new string[] {"AProperty"}, 0, 0,
> CacheKeyType.Object);
> >                       CacheKey aDifferentKey = new CacheKey(factory,
> "STATEMENT", "SQL", new TestClass(ANOTHER_LONG_WITH_SAME_HASHCODE), new
> string[] {"AProperty"}, 0, 0, CacheKeyType.Object);
> >                       Assert.IsFalse(aDifferentKey.Equals(key)); //
> should not be equal.
> >               }
> >       }
> >       public class TestClass
> >       {
> >               private long aProperty;
> >               public TestClass(long aProperty)
> >               {
> >                       this.aProperty = aProperty;
> >               }
> >               public long AProperty
> >               {
> >                       get { return aProperty; }
> >                       set { aProperty = value; }
> >               }
> >       }
> > }
> > ---- UNIT TEST END ----
> > The test passes if you replace this line in CacheKey.Equals():
> >                if (_hashCode != cacheKey._hashCode) return false;
> > with something like this:
> >                if (this._parameter == null && cacheKey._parameter !=
> null) return false;
> >                if (this._parameter != null && cacheKey._parameter ==
> null) return false;
> >                if (!this._parameter.Equals(cacheKey._parameter)) return
> false;
>
> --
> This message is automatically generated by JIRA.
> -
> If you think it was sent incorrectly contact one of the administrators:
>    http://issues.apache.org/jira/secure/Administrators.jspa
> -
> For more information on JIRA, see:
>    http://www.atlassian.com/software/jira
>
>

[jira] Closed: (IBATISNET-118) CacheKey.Equals(object) override can return true when the parameters have the same HashCode but are not equal.

Posted by "Gilles Bayon (JIRA)" <ib...@incubator.apache.org>.
     [ http://issues.apache.org/jira/browse/IBATISNET-118?page=all ]
     
Gilles Bayon closed IBATISNET-118:
----------------------------------

    Fix Version: DataMapper 1.3
     Resolution: Fixed
      Assign To: Gilles Bayon

Invalid patch but solve by another way
In SVN

> CacheKey.Equals(object) override can return true when the parameters have the same HashCode but are not equal.
> --------------------------------------------------------------------------------------------------------------
>
>          Key: IBATISNET-118
>          URL: http://issues.apache.org/jira/browse/IBATISNET-118
>      Project: iBatis for .NET
>         Type: Bug
>   Components: DataMapper
>     Versions: DataMapper 1.2.1
>  Environment: Windows
>     Reporter: Thomas Tannahill
>     Assignee: Gilles Bayon
>      Fix For: DataMapper 1.3

>
> CacheKey.Equals(object) override can return true when the parameters have the same HashCode but are not equal.  This can cause false cache hits.
> Only an issue for complex parameters.
> Failing NUnit test:
> ---- UNIT TEST BEGIN ----
> using IBatisNet.DataMapper;
> using IBatisNet.DataMapper.TypeHandlers;
> using NUnit.Framework;
> namespace IBatisNet.DataAccess
> {
> 	[TestFixture]
> 	public class CacheKeyTests
> 	{
> 		private const long A_LONG = 1L;
> 		private const long ANOTHER_LONG_WITH_SAME_HASHCODE = -9223372034707292159;
> 		
> 		public CacheKeyTests()
> 		{
> 		}
> 		[Test]
> 		public void ShouldNotBeConsideredEqualWhenParametersHaveTheSameHashCodeButAreNotEqual()
> 		{
> 			TypeHandlerFactory factory = new TypeHandlerFactory(); 
> 			// Two cache keys are equal except for the parameter.
> 			CacheKey key = new CacheKey(factory, "STATEMENT", "SQL", new TestClass(A_LONG), new string[] {"AProperty"}, 0, 0, CacheKeyType.Object);
> 			CacheKey aDifferentKey = new CacheKey(factory, "STATEMENT", "SQL", new TestClass(ANOTHER_LONG_WITH_SAME_HASHCODE), new string[] {"AProperty"}, 0, 0, CacheKeyType.Object);
> 			Assert.IsFalse(aDifferentKey.Equals(key)); // should not be equal.
> 		}
> 	}
> 	public class TestClass
> 	{
> 		private long aProperty;
> 		public TestClass(long aProperty)
> 		{
> 			this.aProperty = aProperty;
> 		}
> 		public long AProperty
> 		{
> 			get { return aProperty; }
> 			set { aProperty = value; }
> 		}
> 	}
> }
> ---- UNIT TEST END ----
> The test passes if you replace this line in CacheKey.Equals():
>                if (_hashCode != cacheKey._hashCode) return false;
> with something like this:
>                if (this._parameter == null && cacheKey._parameter != null) return false;
>                if (this._parameter != null && cacheKey._parameter == null) return false;
>                if (!this._parameter.Equals(cacheKey._parameter)) return false;

-- 
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators:
   http://issues.apache.org/jira/secure/Administrators.jspa
-
For more information on JIRA, see:
   http://www.atlassian.com/software/jira


[jira] Commented: (IBATISNET-118) CacheKey.Equals(object) override can return true when the parameters have the same HashCode but are not equal.

Posted by "Jeremy Gray (JIRA)" <ib...@incubator.apache.org>.
    [ http://issues.apache.org/jira/browse/IBATISNET-118?page=comments#action_12355678 ] 

Jeremy Gray commented on IBATISNET-118:
---------------------------------------

This is a dangerous, slippery slope.

In .NET there are two and only two equality semantics: reference and value type.

Assuming that ibatis is now also checking .Equals as opposed to its previous reliance on only GetHashcode, the responsibility falls on the creator of the class being checked for equality, not on ibatis, to perform the appropriate comparison.

Reference types that wish to use a value-type equality semantic must implement the appropriate method overrides themselves (as System.String does, for example).

Ibatis must in turn use only .GetHashcode() and .Equals(...).

Any other expected behaviour indicates that the class being compared has implemented the wrong equality semantic.

> CacheKey.Equals(object) override can return true when the parameters have the same HashCode but are not equal.
> --------------------------------------------------------------------------------------------------------------
>
>          Key: IBATISNET-118
>          URL: http://issues.apache.org/jira/browse/IBATISNET-118
>      Project: iBatis for .NET
>         Type: Bug
>   Components: DataMapper
>     Versions: DataMapper 1.2.1
>  Environment: Windows
>     Reporter: Thomas Tannahill
>     Assignee: Gilles Bayon
>      Fix For: DataMapper 1.3

>
> CacheKey.Equals(object) override can return true when the parameters have the same HashCode but are not equal.  This can cause false cache hits.
> Only an issue for complex parameters.
> Failing NUnit test:
> ---- UNIT TEST BEGIN ----
> using IBatisNet.DataMapper;
> using IBatisNet.DataMapper.TypeHandlers;
> using NUnit.Framework;
> namespace IBatisNet.DataAccess
> {
> 	[TestFixture]
> 	public class CacheKeyTests
> 	{
> 		private const long A_LONG = 1L;
> 		private const long ANOTHER_LONG_WITH_SAME_HASHCODE = -9223372034707292159;
> 		
> 		public CacheKeyTests()
> 		{
> 		}
> 		[Test]
> 		public void ShouldNotBeConsideredEqualWhenParametersHaveTheSameHashCodeButAreNotEqual()
> 		{
> 			TypeHandlerFactory factory = new TypeHandlerFactory(); 
> 			// Two cache keys are equal except for the parameter.
> 			CacheKey key = new CacheKey(factory, "STATEMENT", "SQL", new TestClass(A_LONG), new string[] {"AProperty"}, 0, 0, CacheKeyType.Object);
> 			CacheKey aDifferentKey = new CacheKey(factory, "STATEMENT", "SQL", new TestClass(ANOTHER_LONG_WITH_SAME_HASHCODE), new string[] {"AProperty"}, 0, 0, CacheKeyType.Object);
> 			Assert.IsFalse(aDifferentKey.Equals(key)); // should not be equal.
> 		}
> 	}
> 	public class TestClass
> 	{
> 		private long aProperty;
> 		public TestClass(long aProperty)
> 		{
> 			this.aProperty = aProperty;
> 		}
> 		public long AProperty
> 		{
> 			get { return aProperty; }
> 			set { aProperty = value; }
> 		}
> 	}
> }
> ---- UNIT TEST END ----
> The test passes if you replace this line in CacheKey.Equals():
>                if (_hashCode != cacheKey._hashCode) return false;
> with something like this:
>                if (this._parameter == null && cacheKey._parameter != null) return false;
>                if (this._parameter != null && cacheKey._parameter == null) return false;
>                if (!this._parameter.Equals(cacheKey._parameter)) return false;

-- 
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators:
   http://issues.apache.org/jira/secure/Administrators.jspa
-
For more information on JIRA, see:
   http://www.atlassian.com/software/jira


[jira] Commented: (IBATISNET-118) CacheKey.Equals(object) override can return true when the parameters have the same HashCode but are not equal.

Posted by "Gilles Bayon (JIRA)" <ib...@incubator.apache.org>.
    [ http://issues.apache.org/jira/browse/IBATISNET-118?page=comments#action_12358972 ] 

Gilles Bayon commented on IBATISNET-118:
----------------------------------------

The current code compares each parameter with both their hashcode and a value representation but if you could find a test case that could invalid the current code, you could fix it.

> CacheKey.Equals(object) override can return true when the parameters have the same HashCode but are not equal.
> --------------------------------------------------------------------------------------------------------------
>
>          Key: IBATISNET-118
>          URL: http://issues.apache.org/jira/browse/IBATISNET-118
>      Project: iBatis for .NET
>         Type: Bug
>   Components: DataMapper
>     Versions: DataMapper 1.2.1
>  Environment: Windows
>     Reporter: Thomas Tannahill
>     Assignee: Gilles Bayon
>      Fix For: DataMapper 1.3

>
> CacheKey.Equals(object) override can return true when the parameters have the same HashCode but are not equal.  This can cause false cache hits.
> Only an issue for complex parameters.
> Failing NUnit test:
> ---- UNIT TEST BEGIN ----
> using IBatisNet.DataMapper;
> using IBatisNet.DataMapper.TypeHandlers;
> using NUnit.Framework;
> namespace IBatisNet.DataAccess
> {
> 	[TestFixture]
> 	public class CacheKeyTests
> 	{
> 		private const long A_LONG = 1L;
> 		private const long ANOTHER_LONG_WITH_SAME_HASHCODE = -9223372034707292159;
> 		
> 		public CacheKeyTests()
> 		{
> 		}
> 		[Test]
> 		public void ShouldNotBeConsideredEqualWhenParametersHaveTheSameHashCodeButAreNotEqual()
> 		{
> 			TypeHandlerFactory factory = new TypeHandlerFactory(); 
> 			// Two cache keys are equal except for the parameter.
> 			CacheKey key = new CacheKey(factory, "STATEMENT", "SQL", new TestClass(A_LONG), new string[] {"AProperty"}, 0, 0, CacheKeyType.Object);
> 			CacheKey aDifferentKey = new CacheKey(factory, "STATEMENT", "SQL", new TestClass(ANOTHER_LONG_WITH_SAME_HASHCODE), new string[] {"AProperty"}, 0, 0, CacheKeyType.Object);
> 			Assert.IsFalse(aDifferentKey.Equals(key)); // should not be equal.
> 		}
> 	}
> 	public class TestClass
> 	{
> 		private long aProperty;
> 		public TestClass(long aProperty)
> 		{
> 			this.aProperty = aProperty;
> 		}
> 		public long AProperty
> 		{
> 			get { return aProperty; }
> 			set { aProperty = value; }
> 		}
> 	}
> }
> ---- UNIT TEST END ----
> The test passes if you replace this line in CacheKey.Equals():
>                if (_hashCode != cacheKey._hashCode) return false;
> with something like this:
>                if (this._parameter == null && cacheKey._parameter != null) return false;
>                if (this._parameter != null && cacheKey._parameter == null) return false;
>                if (!this._parameter.Equals(cacheKey._parameter)) return false;

-- 
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators:
   http://issues.apache.org/jira/secure/Administrators.jspa
-
For more information on JIRA, see:
   http://www.atlassian.com/software/jira


[jira] Resolved: (IBATISNET-118) CacheKey.Equals(object) override can return true when the parameters have the same HashCode but are not equal.

Posted by "Gilles Bayon (JIRA)" <ib...@incubator.apache.org>.
     [ http://issues.apache.org/jira/browse/IBATISNET-118?page=all ]
     
Gilles Bayon resolved IBATISNET-118:
------------------------------------

    Resolution: Fixed

In SVN

> CacheKey.Equals(object) override can return true when the parameters have the same HashCode but are not equal.
> --------------------------------------------------------------------------------------------------------------
>
>          Key: IBATISNET-118
>          URL: http://issues.apache.org/jira/browse/IBATISNET-118
>      Project: iBatis for .NET
>         Type: Bug
>   Components: DataMapper
>     Versions: DataMapper 1.2.1
>  Environment: Windows
>     Reporter: Thomas Tannahill
>     Assignee: Gilles Bayon
>      Fix For: DataMapper 1.3

>
> CacheKey.Equals(object) override can return true when the parameters have the same HashCode but are not equal.  This can cause false cache hits.
> Only an issue for complex parameters.
> Failing NUnit test:
> ---- UNIT TEST BEGIN ----
> using IBatisNet.DataMapper;
> using IBatisNet.DataMapper.TypeHandlers;
> using NUnit.Framework;
> namespace IBatisNet.DataAccess
> {
> 	[TestFixture]
> 	public class CacheKeyTests
> 	{
> 		private const long A_LONG = 1L;
> 		private const long ANOTHER_LONG_WITH_SAME_HASHCODE = -9223372034707292159;
> 		
> 		public CacheKeyTests()
> 		{
> 		}
> 		[Test]
> 		public void ShouldNotBeConsideredEqualWhenParametersHaveTheSameHashCodeButAreNotEqual()
> 		{
> 			TypeHandlerFactory factory = new TypeHandlerFactory(); 
> 			// Two cache keys are equal except for the parameter.
> 			CacheKey key = new CacheKey(factory, "STATEMENT", "SQL", new TestClass(A_LONG), new string[] {"AProperty"}, 0, 0, CacheKeyType.Object);
> 			CacheKey aDifferentKey = new CacheKey(factory, "STATEMENT", "SQL", new TestClass(ANOTHER_LONG_WITH_SAME_HASHCODE), new string[] {"AProperty"}, 0, 0, CacheKeyType.Object);
> 			Assert.IsFalse(aDifferentKey.Equals(key)); // should not be equal.
> 		}
> 	}
> 	public class TestClass
> 	{
> 		private long aProperty;
> 		public TestClass(long aProperty)
> 		{
> 			this.aProperty = aProperty;
> 		}
> 		public long AProperty
> 		{
> 			get { return aProperty; }
> 			set { aProperty = value; }
> 		}
> 	}
> }
> ---- UNIT TEST END ----
> The test passes if you replace this line in CacheKey.Equals():
>                if (_hashCode != cacheKey._hashCode) return false;
> with something like this:
>                if (this._parameter == null && cacheKey._parameter != null) return false;
>                if (this._parameter != null && cacheKey._parameter == null) return false;
>                if (!this._parameter.Equals(cacheKey._parameter)) return false;

-- 
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators:
   http://issues.apache.org/jira/secure/Administrators.jspa
-
For more information on JIRA, see:
   http://www.atlassian.com/software/jira


Re: [jira] Commented: (IBATISNET-118) CacheKey.Equals(object) override can return true when the parameters have the same HashCode but are not equal.

Posted by Nathan Maves <Na...@Sun.COM>.
I would but I am still working on getting the ant build process to  
work on my machine.  I am close :)

Nathan

On Nov 30, 2005, at 2:32 PM, Clinton Begin (JIRA) wrote:

>     [ http://issues.apache.org/jira/browse/IBATISNET-118? 
> page=comments#action_12358971 ]
>
> Clinton Begin commented on IBATISNET-118:
> -----------------------------------------
>
>
> Hey guys, would you like me to fix this one?
>
>
>> CacheKey.Equals(object) override can return true when the  
>> parameters have the same HashCode but are not equal.
>> --------------------------------------------------------------------- 
>> -----------------------------------------
>>
>>          Key: IBATISNET-118
>>          URL: http://issues.apache.org/jira/browse/IBATISNET-118
>>      Project: iBatis for .NET
>>         Type: Bug
>>   Components: DataMapper
>>     Versions: DataMapper 1.2.1
>>  Environment: Windows
>>     Reporter: Thomas Tannahill
>>     Assignee: Gilles Bayon
>>      Fix For: DataMapper 1.3
>
>>
>> CacheKey.Equals(object) override can return true when the  
>> parameters have the same HashCode but are not equal.  This can  
>> cause false cache hits.
>> Only an issue for complex parameters.
>> Failing NUnit test:
>> ---- UNIT TEST BEGIN ----
>> using IBatisNet.DataMapper;
>> using IBatisNet.DataMapper.TypeHandlers;
>> using NUnit.Framework;
>> namespace IBatisNet.DataAccess
>> {
>> 	[TestFixture]
>> 	public class CacheKeyTests
>> 	{
>> 		private const long A_LONG = 1L;
>> 		private const long ANOTHER_LONG_WITH_SAME_HASHCODE =  
>> -9223372034707292159;
>> 		
>> 		public CacheKeyTests()
>> 		{
>> 		}
>> 		[Test]
>> 		public void  
>> ShouldNotBeConsideredEqualWhenParametersHaveTheSameHashCodeButAreNotE 
>> qual()
>> 		{
>> 			TypeHandlerFactory factory = new TypeHandlerFactory();
>> 			// Two cache keys are equal except for the parameter.
>> 			CacheKey key = new CacheKey(factory, "STATEMENT", "SQL", new  
>> TestClass(A_LONG), new string[] {"AProperty"}, 0, 0,  
>> CacheKeyType.Object);
>> 			CacheKey aDifferentKey = new CacheKey(factory, "STATEMENT",  
>> "SQL", new TestClass(ANOTHER_LONG_WITH_SAME_HASHCODE), new string 
>> [] {"AProperty"}, 0, 0, CacheKeyType.Object);
>> 			Assert.IsFalse(aDifferentKey.Equals(key)); // should not be equal.
>> 		}
>> 	}
>> 	public class TestClass
>> 	{
>> 		private long aProperty;
>> 		public TestClass(long aProperty)
>> 		{
>> 			this.aProperty = aProperty;
>> 		}
>> 		public long AProperty
>> 		{
>> 			get { return aProperty; }
>> 			set { aProperty = value; }
>> 		}
>> 	}
>> }
>> ---- UNIT TEST END ----
>> The test passes if you replace this line in CacheKey.Equals():
>>                if (_hashCode != cacheKey._hashCode) return false;
>> with something like this:
>>                if (this._parameter == null && cacheKey._parameter ! 
>> = null) return false;
>>                if (this._parameter != null && cacheKey._parameter  
>> == null) return false;
>>                if (!this._parameter.Equals(cacheKey._parameter))  
>> return false;
>
> -- 
> This message is automatically generated by JIRA.
> -
> If you think it was sent incorrectly contact one of the  
> administrators:
>    http://issues.apache.org/jira/secure/Administrators.jspa
> -
> For more information on JIRA, see:
>    http://www.atlassian.com/software/jira
>


[jira] Commented: (IBATISNET-118) CacheKey.Equals(object) override can return true when the parameters have the same HashCode but are not equal.

Posted by "Clinton Begin (JIRA)" <ib...@incubator.apache.org>.
    [ http://issues.apache.org/jira/browse/IBATISNET-118?page=comments#action_12358971 ] 

Clinton Begin commented on IBATISNET-118:
-----------------------------------------


Hey guys, would you like me to fix this one?


> CacheKey.Equals(object) override can return true when the parameters have the same HashCode but are not equal.
> --------------------------------------------------------------------------------------------------------------
>
>          Key: IBATISNET-118
>          URL: http://issues.apache.org/jira/browse/IBATISNET-118
>      Project: iBatis for .NET
>         Type: Bug
>   Components: DataMapper
>     Versions: DataMapper 1.2.1
>  Environment: Windows
>     Reporter: Thomas Tannahill
>     Assignee: Gilles Bayon
>      Fix For: DataMapper 1.3

>
> CacheKey.Equals(object) override can return true when the parameters have the same HashCode but are not equal.  This can cause false cache hits.
> Only an issue for complex parameters.
> Failing NUnit test:
> ---- UNIT TEST BEGIN ----
> using IBatisNet.DataMapper;
> using IBatisNet.DataMapper.TypeHandlers;
> using NUnit.Framework;
> namespace IBatisNet.DataAccess
> {
> 	[TestFixture]
> 	public class CacheKeyTests
> 	{
> 		private const long A_LONG = 1L;
> 		private const long ANOTHER_LONG_WITH_SAME_HASHCODE = -9223372034707292159;
> 		
> 		public CacheKeyTests()
> 		{
> 		}
> 		[Test]
> 		public void ShouldNotBeConsideredEqualWhenParametersHaveTheSameHashCodeButAreNotEqual()
> 		{
> 			TypeHandlerFactory factory = new TypeHandlerFactory(); 
> 			// Two cache keys are equal except for the parameter.
> 			CacheKey key = new CacheKey(factory, "STATEMENT", "SQL", new TestClass(A_LONG), new string[] {"AProperty"}, 0, 0, CacheKeyType.Object);
> 			CacheKey aDifferentKey = new CacheKey(factory, "STATEMENT", "SQL", new TestClass(ANOTHER_LONG_WITH_SAME_HASHCODE), new string[] {"AProperty"}, 0, 0, CacheKeyType.Object);
> 			Assert.IsFalse(aDifferentKey.Equals(key)); // should not be equal.
> 		}
> 	}
> 	public class TestClass
> 	{
> 		private long aProperty;
> 		public TestClass(long aProperty)
> 		{
> 			this.aProperty = aProperty;
> 		}
> 		public long AProperty
> 		{
> 			get { return aProperty; }
> 			set { aProperty = value; }
> 		}
> 	}
> }
> ---- UNIT TEST END ----
> The test passes if you replace this line in CacheKey.Equals():
>                if (_hashCode != cacheKey._hashCode) return false;
> with something like this:
>                if (this._parameter == null && cacheKey._parameter != null) return false;
>                if (this._parameter != null && cacheKey._parameter == null) return false;
>                if (!this._parameter.Equals(cacheKey._parameter)) return false;

-- 
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators:
   http://issues.apache.org/jira/secure/Administrators.jspa
-
For more information on JIRA, see:
   http://www.atlassian.com/software/jira


[jira] Commented: (IBATISNET-118) CacheKey.Equals(object) override can return true when the parameters have the same HashCode but are not equal.

Posted by "Jeremy Gray (JIRA)" <ib...@incubator.apache.org>.
    [ http://issues.apache.org/jira/browse/IBATISNET-118?page=comments#action_12358975 ] 

Jeremy Gray commented on IBATISNET-118:
---------------------------------------

Gilles: Having reviewed the CacheKey code _again_ this fall (after first looking at it back in the spring) I can tell you that it does not do what you describe. Types that need to be treated as special cases (e.g. Hashtable) given the needs of the application are currently using only hashcode and perhaps Equals comparisons. Other types are treated as a special case (walking their properties) when the .NET equality semantics demand that they strictly be compared based on GetHashCode and Equals. Even given the current logic, GetHashCode and Equals are not internally consistent - one of them applies different special cases than the other.

Clinton: Our company would love it to be fixed for us :), but will be happy to implement the fix at the point in our schedule where it becomes critical. That said, at the time we can implement it I doubt we'll be able to verify against the full set of ibatis.net test cases, so we might need a hand in verification from someone who is already set up to do so.

> CacheKey.Equals(object) override can return true when the parameters have the same HashCode but are not equal.
> --------------------------------------------------------------------------------------------------------------
>
>          Key: IBATISNET-118
>          URL: http://issues.apache.org/jira/browse/IBATISNET-118
>      Project: iBatis for .NET
>         Type: Bug
>   Components: DataMapper
>     Versions: DataMapper 1.2.1
>  Environment: Windows
>     Reporter: Thomas Tannahill
>     Assignee: Gilles Bayon
>      Fix For: DataMapper 1.3

>
> CacheKey.Equals(object) override can return true when the parameters have the same HashCode but are not equal.  This can cause false cache hits.
> Only an issue for complex parameters.
> Failing NUnit test:
> ---- UNIT TEST BEGIN ----
> using IBatisNet.DataMapper;
> using IBatisNet.DataMapper.TypeHandlers;
> using NUnit.Framework;
> namespace IBatisNet.DataAccess
> {
> 	[TestFixture]
> 	public class CacheKeyTests
> 	{
> 		private const long A_LONG = 1L;
> 		private const long ANOTHER_LONG_WITH_SAME_HASHCODE = -9223372034707292159;
> 		
> 		public CacheKeyTests()
> 		{
> 		}
> 		[Test]
> 		public void ShouldNotBeConsideredEqualWhenParametersHaveTheSameHashCodeButAreNotEqual()
> 		{
> 			TypeHandlerFactory factory = new TypeHandlerFactory(); 
> 			// Two cache keys are equal except for the parameter.
> 			CacheKey key = new CacheKey(factory, "STATEMENT", "SQL", new TestClass(A_LONG), new string[] {"AProperty"}, 0, 0, CacheKeyType.Object);
> 			CacheKey aDifferentKey = new CacheKey(factory, "STATEMENT", "SQL", new TestClass(ANOTHER_LONG_WITH_SAME_HASHCODE), new string[] {"AProperty"}, 0, 0, CacheKeyType.Object);
> 			Assert.IsFalse(aDifferentKey.Equals(key)); // should not be equal.
> 		}
> 	}
> 	public class TestClass
> 	{
> 		private long aProperty;
> 		public TestClass(long aProperty)
> 		{
> 			this.aProperty = aProperty;
> 		}
> 		public long AProperty
> 		{
> 			get { return aProperty; }
> 			set { aProperty = value; }
> 		}
> 	}
> }
> ---- UNIT TEST END ----
> The test passes if you replace this line in CacheKey.Equals():
>                if (_hashCode != cacheKey._hashCode) return false;
> with something like this:
>                if (this._parameter == null && cacheKey._parameter != null) return false;
>                if (this._parameter != null && cacheKey._parameter == null) return false;
>                if (!this._parameter.Equals(cacheKey._parameter)) return false;

-- 
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators:
   http://issues.apache.org/jira/secure/Administrators.jspa
-
For more information on JIRA, see:
   http://www.atlassian.com/software/jira


[jira] Closed: (IBATISNET-118) CacheKey.Equals(object) override can return true when the parameters have the same HashCode but are not equal.

Posted by "Gilles Bayon (JIRA)" <ib...@incubator.apache.org>.
     [ http://issues.apache.org/jira/browse/IBATISNET-118?page=all ]
     
Gilles Bayon closed IBATISNET-118:
----------------------------------


> CacheKey.Equals(object) override can return true when the parameters have the same HashCode but are not equal.
> --------------------------------------------------------------------------------------------------------------
>
>          Key: IBATISNET-118
>          URL: http://issues.apache.org/jira/browse/IBATISNET-118
>      Project: iBatis for .NET
>         Type: Bug
>   Components: DataMapper
>     Versions: DataMapper 1.2.1
>  Environment: Windows
>     Reporter: Thomas Tannahill
>     Assignee: Gilles Bayon
>      Fix For: DataMapper 1.3

>
> CacheKey.Equals(object) override can return true when the parameters have the same HashCode but are not equal.  This can cause false cache hits.
> Only an issue for complex parameters.
> Failing NUnit test:
> ---- UNIT TEST BEGIN ----
> using IBatisNet.DataMapper;
> using IBatisNet.DataMapper.TypeHandlers;
> using NUnit.Framework;
> namespace IBatisNet.DataAccess
> {
> 	[TestFixture]
> 	public class CacheKeyTests
> 	{
> 		private const long A_LONG = 1L;
> 		private const long ANOTHER_LONG_WITH_SAME_HASHCODE = -9223372034707292159;
> 		
> 		public CacheKeyTests()
> 		{
> 		}
> 		[Test]
> 		public void ShouldNotBeConsideredEqualWhenParametersHaveTheSameHashCodeButAreNotEqual()
> 		{
> 			TypeHandlerFactory factory = new TypeHandlerFactory(); 
> 			// Two cache keys are equal except for the parameter.
> 			CacheKey key = new CacheKey(factory, "STATEMENT", "SQL", new TestClass(A_LONG), new string[] {"AProperty"}, 0, 0, CacheKeyType.Object);
> 			CacheKey aDifferentKey = new CacheKey(factory, "STATEMENT", "SQL", new TestClass(ANOTHER_LONG_WITH_SAME_HASHCODE), new string[] {"AProperty"}, 0, 0, CacheKeyType.Object);
> 			Assert.IsFalse(aDifferentKey.Equals(key)); // should not be equal.
> 		}
> 	}
> 	public class TestClass
> 	{
> 		private long aProperty;
> 		public TestClass(long aProperty)
> 		{
> 			this.aProperty = aProperty;
> 		}
> 		public long AProperty
> 		{
> 			get { return aProperty; }
> 			set { aProperty = value; }
> 		}
> 	}
> }
> ---- UNIT TEST END ----
> The test passes if you replace this line in CacheKey.Equals():
>                if (_hashCode != cacheKey._hashCode) return false;
> with something like this:
>                if (this._parameter == null && cacheKey._parameter != null) return false;
>                if (this._parameter != null && cacheKey._parameter == null) return false;
>                if (!this._parameter.Equals(cacheKey._parameter)) return false;

-- 
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators:
   http://issues.apache.org/jira/secure/Administrators.jspa
-
For more information on JIRA, see:
   http://www.atlassian.com/software/jira


[jira] Reopened: (IBATISNET-118) CacheKey.Equals(object) override can return true when the parameters have the same HashCode but are not equal.

Posted by "Clinton Begin (JIRA)" <ib...@incubator.apache.org>.
     [ http://issues.apache.org/jira/browse/IBATISNET-118?page=all ]
     
Clinton Begin reopened IBATISNET-118:
-------------------------------------



This is still an issue.  The equals method is using hashcode exclusively to compare the values.  It cannot, no matter what the hashcode algorithm is, 32 bits will never be enough to compare uniqueness.

So....

The Equals method of the cachekey object should....

1) use hashcode for each parameter to determine initial match (for performance)

2) double-check the using a true equals method that directly compares each parameter for exact equality.

There is NO other way to do this.  

We had the same problem in Java, and it's a pretty serious bug...anything that ends up returning incorrect results from the DB is our highest priority.

Let me know if you'd like an explanation of the sequence of events, problem and solution from the Java version.

Cheers,
Clinton

> CacheKey.Equals(object) override can return true when the parameters have the same HashCode but are not equal.
> --------------------------------------------------------------------------------------------------------------
>
>          Key: IBATISNET-118
>          URL: http://issues.apache.org/jira/browse/IBATISNET-118
>      Project: iBatis for .NET
>         Type: Bug
>   Components: DataMapper
>     Versions: DataMapper 1.2.1
>  Environment: Windows
>     Reporter: Thomas Tannahill
>     Assignee: Gilles Bayon
>      Fix For: DataMapper 1.3

>
> CacheKey.Equals(object) override can return true when the parameters have the same HashCode but are not equal.  This can cause false cache hits.
> Only an issue for complex parameters.
> Failing NUnit test:
> ---- UNIT TEST BEGIN ----
> using IBatisNet.DataMapper;
> using IBatisNet.DataMapper.TypeHandlers;
> using NUnit.Framework;
> namespace IBatisNet.DataAccess
> {
> 	[TestFixture]
> 	public class CacheKeyTests
> 	{
> 		private const long A_LONG = 1L;
> 		private const long ANOTHER_LONG_WITH_SAME_HASHCODE = -9223372034707292159;
> 		
> 		public CacheKeyTests()
> 		{
> 		}
> 		[Test]
> 		public void ShouldNotBeConsideredEqualWhenParametersHaveTheSameHashCodeButAreNotEqual()
> 		{
> 			TypeHandlerFactory factory = new TypeHandlerFactory(); 
> 			// Two cache keys are equal except for the parameter.
> 			CacheKey key = new CacheKey(factory, "STATEMENT", "SQL", new TestClass(A_LONG), new string[] {"AProperty"}, 0, 0, CacheKeyType.Object);
> 			CacheKey aDifferentKey = new CacheKey(factory, "STATEMENT", "SQL", new TestClass(ANOTHER_LONG_WITH_SAME_HASHCODE), new string[] {"AProperty"}, 0, 0, CacheKeyType.Object);
> 			Assert.IsFalse(aDifferentKey.Equals(key)); // should not be equal.
> 		}
> 	}
> 	public class TestClass
> 	{
> 		private long aProperty;
> 		public TestClass(long aProperty)
> 		{
> 			this.aProperty = aProperty;
> 		}
> 		public long AProperty
> 		{
> 			get { return aProperty; }
> 			set { aProperty = value; }
> 		}
> 	}
> }
> ---- UNIT TEST END ----
> The test passes if you replace this line in CacheKey.Equals():
>                if (_hashCode != cacheKey._hashCode) return false;
> with something like this:
>                if (this._parameter == null && cacheKey._parameter != null) return false;
>                if (this._parameter != null && cacheKey._parameter == null) return false;
>                if (!this._parameter.Equals(cacheKey._parameter)) return false;

-- 
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators:
   http://issues.apache.org/jira/secure/Administrators.jspa
-
For more information on JIRA, see:
   http://www.atlassian.com/software/jira