[
https://hibernate.onjira.com/browse/HHH-7113?page=com.atlassian.jira.plug...
]
Guenther Demetz edited comment on HHH-7113 at 2/28/12 9:28 AM:
---------------------------------------------------------------
In my opinion the naturalIdResolutionCacheMap must always be filled using the persister of
the declaring class (= the highest class in hierarchy which satisfies the given
naturalIdValues),
see following example:
class A
@NaturalId
key1
class AA extends A
@NaturalId
key2
class AAA extends AA
---------------------------
assertTrue (session.bySimpleNaturalId(A.class).load(key1) instanceof AAA); // this is
possible,
//persister of class A should be cache-key: naturalIdResolutionCacheMap.put( persisterA,
entityNaturalIdResolutionCache );
assertTrue (session.byNaturalId(AA.class).using("key1",
key1).using("key2", key2).load() instanceof AAA); // also this is possible,
//persister of class AA should be cache-key: naturalIdResolutionCacheMap.put( persisterAA,
entityNaturalIdResolutionCache );
assertTrue (session.byNaturalId(AAA.class).using("key1",
key1).using("key2", key2).load() instanceof AAA); //this should produce a
in-memory-hit in the NaturalId-cache of persisterAA
Thus, similiar to StatefulPersistenceContext#validateNaturalId(EntityPersister persister,
Object[] naturalIdValues)
we will need a method which returns the correct persister for NaturalId-caching, something
like following:
private EntityPersister findProperEntityPersisterForNaturalIdValues(EntityPersister
persister, Object[] naturalIdValues) {
EntityPersister ret = persister;
while (persister.hasSuperClassPersister()) {
try {
validateNaturalId(ret.getSuperClassPersister(),naturalIdValues);
ret = ret.getPersisterForSuperClass();
}
catch (IllegalArgumentException i) {
break;
}
}
return ret;
}
---
Then modify the puts into naturalIdResolutionCacheMap as follows:
naturalIdResolutionCacheMap.put(findProperEntityPersisterForNaturalIdValues(persister,naturalIdValues),
entityNaturalIdResolutionCache );
---------------------------------------------
Next thing to consider are updates and deletions.
In the example above the instance AAA finally is cached 2 times in NaturalIdCache:
once with key1 in the cache of persisterA and another time with key1+key2 in the cache of
persisterAA.
Thus when deleting instance AAA or updating key1 in the AAA instance, both cache entries
have to be synchronized.
was (Author: pb00067):
In my opinion the naturalIdResolutionCacheMap must always be filled using the
persister of the declaring class (= the highest class in hierarchy which satisfies the
given naturalIdValues),
see following example:
class A
@NaturalId
key1
class AA extends A
@NaturalId
key2
class AAA extends AA
---------------------------
assertTrue (session.bySimpleNaturalId(A.class).load(key1) instanceof AAA); // this is
possible,
//persister of class A should be cache-key: naturalIdResolutionCacheMap.put( persisterA,
entityNaturalIdResolutionCache );
assertTrue (session.byNaturalId(AA.class).using("key1",
key1).using("key2", key2).load() instanceof AAA); // also this is possible,
//persister of class AA should be cache-key: naturalIdResolutionCacheMap.put( persisterAA,
entityNaturalIdResolutionCache );
assertTrue (session.byNaturalId(AAA.class).using("key1",
key1).using("key2", key2).load() instanceof AAA); //this should produce a
in-memory-hit in the NaturalId-cache of persisterAA
Thus, similiar to StatefulPersistenceContext#validateNaturalId(EntityPersister persister,
Object[] naturalIdValues)
we will need a method which returns the correct persister for NaturalId-caching, something
like following:
private EntityPersister findProperEntityPersisterForNaturalIdValues(EntityPersister
persister, Object[] naturalIdValues) {
EntityPersister ret = persister;
while (persister.hasSuperClassPersister()) {
try {
validateNaturalId(ret.getSuperClassPersister(),naturalIdValues);
ret = ret.getPersisterForSuperClass();
}
catch (IllegalArgumentException i) {
break;
}
}
return ret;
}
--------------------------------------------------------------------------------------------------
Then modify the puts into naturalIdResolutionCacheMap as follows:
naturalIdResolutionCacheMap.put(findProperEntityPersisterForNaturalIdValues(persister,naturalIdValues),
entityNaturalIdResolutionCache );
Next thing to consider are updated and deletions.
In the example above the instance AAA finally is cached 2 times in NaturalIdCache:
once with key1 in the cache of persisterA and another time with key1+key2 in the cache of
persisterAA.
Thus when deleting instance AAA or updating key1 in the AAA instance, both cache entries
have to be synchronized.
NaturalIdLoadAccess not properly working on mutable NaturalId's
---------------------------------------------------------------
Key: HHH-7113
URL:
https://hibernate.onjira.com/browse/HHH-7113
Project: Hibernate ORM
Issue Type: Bug
Components: core
Affects Versions: 4.1.0
Environment: Hibernate4.1.0, db independent (HSQLDB used in attached testcase)
Reporter: Guenther Demetz
Labels: naturalId
Attachments: EnhancedTestCaseModifieableNaturalId.jar,
TestCaseModifieableNaturalId.jar
Original Estimate: 16h
Remaining Estimate: 16h
After updating the value of a mutable NaturalId, the entity object can be retrieved with
the new value, but also with the old value.
assertNotSame(session.bySimpleNaturalId(C.class).load("1"),
session.bySimpleNaturalId(C.class).load("3")); --> failing
See attached testcase:
On deletions the internal NaturalId cache is synchronized properly (testDeleteNaturalId)
but not on modifications (testModifieableNaturalId)
--
This message is automatically generated by JIRA.
For more information on JIRA, see:
http://www.atlassian.com/software/jira