[hibernate-issues] [Hibernate-JIRA] Commented: (HHH-7287) Problem in caching proper natural-id-values when obtaining result by naturalIdQuery

Guenther Demetz (JIRA) noreply at atlassian.com
Wed May 2 08:03:48 EDT 2012


    [ https://hibernate.onjira.com/browse/HHH-7287?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=46475#comment-46475 ] 

Guenther Demetz commented on HHH-7287:
--------------------------------------

After rethinking about, I changed my opinion about the SOLUTION PROPOSAL.
Should this issue ever be fixed, then I propose following solution:

After mutable natural-id lookup was resolved through query:
1. check if concerning entity object is already loaded into persistence context
2. if not, then proceed as usual (= cache the natural-id-values by taking the natural-id-values from search parameters)
3. if yes, then do not cache again natural-id's, because:
    a) they surely are already cached.
    b) due to the inline-natural-id-synch process, the cached natural-id-values may already have been changed

My first proposal did not consider point b)
Of course this extra handling should only be applied for mutable natural-ids, avoiding overhead for immutables.
       


> Problem in caching proper natural-id-values when obtaining result by naturalIdQuery
> -----------------------------------------------------------------------------------
>
>                 Key: HHH-7287
>                 URL: https://hibernate.onjira.com/browse/HHH-7287
>             Project: Hibernate ORM
>          Issue Type: Bug
>          Components: core
>    Affects Versions: 4.1.2
>         Environment: Database access with isolation level < SNAPSHOT
>            Reporter: Guenther Demetz
>
> Problem was originally exposed by Madhumita Sadhukhan in a email to hibernate-dev at lists.jboss.org at Fri 4/27/2012 .
> The bug (email point 6) get isolated by following matrix-test-case:
> {code:title=org.hibernate.test.naturalid.mutable.MutableNaturalIdTest.java|borderStyle=solid}
>         @Test
> 	public void testModificationInOtherSession() {
> 		Session s = openSession();
> 		Transaction t = s.beginTransaction();
> 		User u = new User( "gavin", "hb", "secret" );
> 		s.persist( u );
> 		t.commit();
> 		s.close();
> 		s = openSession();
> 		
> 		// Use transactionless session
> 		assertNotNull( s.byNaturalId( User.class ).using( "name", "gavin" ).using( "org", "hb" ).load());
> 		// CHANGE natural-id values in another session
> 		Session other = openSession();
> 		other.beginTransaction();
> 		u = (User) other.byId( User.class ).getReference( u.getId() );
> 		u.setOrg( "zz" );
> 		other.getTransaction().commit();
> 		other.close();
> 		// CHANGE APPLIED
> 		
> 		u = (User) s.byId( User.class ).getReference( u.getId() );
> 		assertEquals(u, s.byNaturalId( User.class ).using( "name", "gavin" ).using( "org", "hb" ).load()); // found with cached old-values, OK
> 		
> 		
> 		User u2 = (User) s.byNaturalId( User.class ).using( "name", "gavin" ).using( "org", "zz" ).load();  // the internal query will 'see' the new values, because isolation level < SERIALIZABLE
> 		assertEquals(u, u2); // is it right here having u2 != null ? Yes, if we continue to see NaturalIdLoadAccess as a plain query. Maybe something to discuss
> 		assertEquals("hb", u2.getOrg()); // entity itself must still contain the old value
> 		assertNotNull( s.byNaturalId( User.class ).using( "name", "gavin" ).using( "org", "hb" ).load()); // this fails, that's the bug
> 		s.close();
> 		s = openSession();
> 		s.beginTransaction();
> 		s.delete( u );
> 		s.getTransaction().commit();
> 		s.close();
> 	}
> {code}
> CAUSE:
> The problem raises, when natural-id get resolved by query.
> Here Hiberante uses the search-natural-id values for updating the cache, probably not being aware that in such situation they could differ from the natural-id-values in the current entity state. The cache-update then detects the old-values as obsolete and removes them, this explains why the second lookup with old values suddently returns null.
> SOLUTION PROPOSAL:
> After natural-id get resolved from query, first load the entity by identifier, and then cache the natural-id-values taking them from the entity state.

--
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