[hibernate-issues] [Hibernate-JIRA] Issue Comment Edited: (HHH-7113) NaturalIdLoadAccess not properly working on mutable NaturalId's
Guenther Demetz (JIRA)
noreply at atlassian.com
Tue Feb 28 10:28:50 EST 2012
[ https://hibernate.onjira.com/browse/HHH-7113?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=45714#comment-45714 ]
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
More information about the hibernate-issues
mailing list