-
Notifications
You must be signed in to change notification settings - Fork 934
Recompute hashcodes on deserialization #1891
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,5 @@ | ||
using System; | ||
using System.Runtime.Serialization; | ||
using NHibernate.Engine; | ||
using NHibernate.Type; | ||
|
||
|
@@ -10,12 +11,15 @@ namespace NHibernate.Cache | |
/// keys which do not properly implement equals()/hashCode(). | ||
/// </summary> | ||
[Serializable] | ||
public class CacheKey | ||
public class CacheKey : IDeserializationCallback | ||
{ | ||
private readonly object key; | ||
private readonly IType type; | ||
private readonly string entityOrRoleName; | ||
private readonly int hashCode; | ||
// hashcode may vary among processes, they cannot be stored and have to be re-computed after deserialization | ||
[NonSerialized] | ||
private int? _hashCode; | ||
private readonly ISessionFactoryImplementor _factory; | ||
|
||
/// <summary> | ||
/// Construct a new key for a collection or entity instance. | ||
|
@@ -31,7 +35,9 @@ public CacheKey(object id, IType type, string entityOrRoleName, ISessionFactoryI | |
key = id; | ||
this.type = type; | ||
this.entityOrRoleName = entityOrRoleName; | ||
hashCode = type.GetHashCode(key, factory); | ||
_factory = factory; | ||
|
||
_hashCode = GenerateHashCode(); | ||
} | ||
|
||
//Mainly for SysCache and Memcache | ||
|
@@ -50,7 +56,22 @@ public override bool Equals(object obj) | |
|
||
public override int GetHashCode() | ||
{ | ||
return hashCode; | ||
// If the object is put in a set or dictionary during deserialization, the hashcode will not yet be | ||
// computed. Compute the hashcode on the fly. So long as this happens only during deserialization, there | ||
// will be no thread safety issues. For the hashcode to be always defined after deserialization, the | ||
// deserialization callback is used. | ||
return _hashCode ?? GenerateHashCode(); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I could have written it There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. code looks much more readable than before There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I have some comments at QueryKey and FilterKey, but i test it and it works. |
||
} | ||
|
||
/// <inheritdoc /> | ||
public void OnDeserialization(object sender) | ||
{ | ||
_hashCode = GenerateHashCode(); | ||
} | ||
|
||
private int GenerateHashCode() | ||
{ | ||
return type.GetHashCode(key, _factory); | ||
} | ||
|
||
public object Key | ||
|
@@ -63,4 +84,4 @@ public string EntityOrRoleName | |
get { return entityOrRoleName; } | ||
} | ||
} | ||
} | ||
} |
Uh oh!
There was an error while loading. Please reload this page.