]
Steve Ash commented on HHH-7258:
--------------------------------
Just in case anyone else stumbles upon this -- the most obvious and best solution is just
to use the UUID class for a PK id type. With a @Column(length=16) this maps to a
binary[16] in the database and hibernate's native UUIDBinaryType works just fine.
Then we avoid all this primitive array nonsense entire.
I just modified our custom generator to return UUID instances constructed with two longs.
Much better.
NaturalIdCacheKey equals method doesn't work for primitive array
types
----------------------------------------------------------------------
Key: HHH-7258
URL:
https://hibernate.onjira.com/browse/HHH-7258
Project: Hibernate ORM
Issue Type: Bug
Components: core
Affects Versions: 4.1.2
Environment: Hibernate 4.1.2
SQL 2008
Reporter: Steve Ash
I have entities like (shorthand):
{code}
@Entity
@Cache
public class Parent {
@Id
private byte[] id;
}
@Entity
@Cache
@NaturalIdCache
public class Child {
@Id
private byte[] id;
@ManyToOne
@NaturalId
private Parent parent;
@NaturalId
private String name;
}
{code}
So the naturalId is a compound key made up of a FK reference to the parent + the name of
the child (i.e. for a single parent, all of the childrens names are unique).
I always get a cache miss in the 2nd level cache when I try to load this by natural key
using something like:
{code}
Parent p = ... // attached parent instance
return sf.getCurrentSession()
.byNaturalId(Child.class)
.using("parent", p)
.using("name", childName)
.load();
{code}
I stepped through the code and found that eventually an instance of {{NaturalIdCacheKey}}
is built with a field {{naturalIdValues}}. In the Child instance above this
naturalIdValues would be an array of size 2. The [0] element is a byte[] reference, and
the [1] element is the child name string.
While I can see in the debugger that my Child instance is present in the natural Id
cache, the equals method on NaturalIdCacheKey just uses Array.equals on naturalIdValues.
Thus, it does a reference equals on my primitive byte[] for the parent's PK value.
While the values in the byte array are the same, they are different instances of course,
and thus the reference equals returns false, and I never retrieve this from the natural id
cache.
Thinking I would be clever, I replaced this with an @Embeddable component that wrapped
the byte[] and implemented my own equals, but Hibernate core _disassembles_ the component
to build the naturalIdCacheKey which defeats my component and so we end up with the same
problem.
I have run in to a similar problem in HHH-7180 so clearly theres not too many of us that
are using binary storage for GUIDs. Is everyone else just storing as 32byte strings? Or
22 byte case-sensitive coalation strings? Or an @embedded with two longs?
I'll build a test case that replicates this at some point soon.
--
This message is automatically generated by JIRA.
For more information on JIRA, see: