Good, and good. :)
It’s been a while since I dug into
that part of the ibatis code (the last time was when I was running into some caching
issues I now suspect were due to passing a domain object in without using an
appropriate parameter map), and I’ll have to take another look some time
soon, but if all is as well as it seems, I have to admit that I’m still a
bit confused by the reopening of the JIRA. It still implies that some class,
somewhere, is implementing the wrong equality semantic (or isn’t
implementing its own at all and is instead being compared via comparison logic
placed somewhere outside of that class), not that the caching code needs to go
beyond .Equals. In any case, I’ll refrain from further comment until I
have a chance to take a fresh walk through the code. :)
Jeremy
From: Clinton Begin
[mailto:[EMAIL PROTECTED]
Sent: Monday, October 24, 2005
6:08 PM
To: [email protected]
Subject: Re: [jira] Reopened:
(IBATISNET-118) CacheKey.Equals(object) override can return true when the
parameters have the same HashCode but are not equal.
You're point is correct, but the good news is it is also irrelevant. :-)
iBATIS only supports the types supported by ADO.NET as
parameters. Therefore, the only types ever being compared will be
strings, ints, etc....
iBATIS doesn't compare the parmeter class using its equas method, it compares
each parameter of the statement as mapped from the class by the parameter map.
Cheers,
Clinton
On 10/24/05, Jeremy
Gray <[EMAIL PROTECTED]>
wrote:
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.
Jeremy Gray
-----Original Message-----
From: Clinton Begin (JIRA) [mailto:[email protected]]
Sent: Monday, October 24, 2005 4:07 PM
To: [email protected]
Subject: [jira] Reopened: (IBATISNET-118) CacheKey.Equals(object)
override can return true when the parameters have the same HashCode but
are not equal.
[ 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
ShouldNotBeConsideredEqualWhenParametersHaveTheSameHashCodeButAreNotEqua
l()
>
{
>
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