mirror of
https://github.com/hibernate/hibernate-orm
synced 2025-02-10 05:04:52 +00:00
HHH-7377 - NullPointerException in conjunction with natural IDs after Session.clear()
(cherry picked from commit 785e2d869e0141e3f1b120667d0e612906b73274)
This commit is contained in:
parent
502542d2b6
commit
e5f0db2455
@ -2092,6 +2092,15 @@ public void handleSynchronization(EntityPersister persister, Serializable pk, Ob
|
|||||||
public void cleanupFromSynchronizations() {
|
public void cleanupFromSynchronizations() {
|
||||||
naturalIdXrefDelegate.unStashInvalidNaturalIdReferences();
|
naturalIdXrefDelegate.unStashInvalidNaturalIdReferences();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void handleEviction(Object object, EntityPersister persister, Serializable identifier) {
|
||||||
|
naturalIdXrefDelegate.removeNaturalIdCrossReference(
|
||||||
|
persister,
|
||||||
|
identifier,
|
||||||
|
findCachedNaturalId( persister, identifier )
|
||||||
|
);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -830,6 +830,15 @@ public void manageSharedNaturalIdCrossReference(
|
|||||||
* of old values as no longer valid.
|
* of old values as no longer valid.
|
||||||
*/
|
*/
|
||||||
public void cleanupFromSynchronizations();
|
public void cleanupFromSynchronizations();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called on {@link org.hibernate.Session#evict} to give a chance to clean up natural-id cross refs.
|
||||||
|
*
|
||||||
|
* @param object The entity instance.
|
||||||
|
* @param persister The entity persister
|
||||||
|
* @param identifier The entity identifier
|
||||||
|
*/
|
||||||
|
public void handleEviction(Object object, EntityPersister persister, Serializable identifier);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -80,7 +80,7 @@ public void onEvict(EvictEvent event) throws HibernateException {
|
|||||||
if ( !li.isUninitialized() ) {
|
if ( !li.isUninitialized() ) {
|
||||||
final Object entity = persistenceContext.removeEntity( key );
|
final Object entity = persistenceContext.removeEntity( key );
|
||||||
if ( entity != null ) {
|
if ( entity != null ) {
|
||||||
EntityEntry e = event.getSession().getPersistenceContext().removeEntry( entity );
|
EntityEntry e = persistenceContext.removeEntry( entity );
|
||||||
doEvict( entity, key, e.getPersister(), event.getSession() );
|
doEvict( entity, key, e.getPersister(), event.getSession() );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -106,6 +106,10 @@ protected void doEvict(
|
|||||||
LOG.tracev( "Evicting {0}", MessageHelper.infoString( persister ) );
|
LOG.tracev( "Evicting {0}", MessageHelper.infoString( persister ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ( persister.hasNaturalIdentifier() ) {
|
||||||
|
session.getPersistenceContext().getNaturalIdHelper().handleEviction( object, persister, key.getIdentifier() );
|
||||||
|
}
|
||||||
|
|
||||||
// remove all collections for the entity from the session-level cache
|
// remove all collections for the entity from the session-level cache
|
||||||
if ( persister.hasCollections() ) {
|
if ( persister.hasCollections() ) {
|
||||||
new EvictVisitor( session ).process( object, persister );
|
new EvictVisitor( session ).process( object, persister );
|
||||||
|
@ -2491,12 +2491,12 @@ protected void performAnyNeededCrossReferenceSynchronizations() {
|
|||||||
// synchronization (this process) was disabled
|
// synchronization (this process) was disabled
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if ( ! isTransactionInProgress() ) {
|
if ( entityPersister.getEntityMetamodel().hasImmutableNaturalId() ) {
|
||||||
// not in a transaction so skip synchronization
|
// only mutable natural-ids need this processing
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if ( entityPersister.getEntityMetamodel().hasImmutableNaturalId() ) {
|
if ( ! isTransactionInProgress() ) {
|
||||||
// only mutable natural-ids need this processing
|
// not in a transaction so skip synchronization
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2505,6 +2505,16 @@ protected void performAnyNeededCrossReferenceSynchronizations() {
|
|||||||
final Object entity = getPersistenceContext().getEntity( entityKey );
|
final Object entity = getPersistenceContext().getEntity( entityKey );
|
||||||
final EntityEntry entry = getPersistenceContext().getEntry( entity );
|
final EntityEntry entry = getPersistenceContext().getEntry( entity );
|
||||||
|
|
||||||
|
if ( entry == null ) {
|
||||||
|
if ( LOG.isDebugEnabled() ) {
|
||||||
|
LOG.debug(
|
||||||
|
"Cached natural-id/pk resolution linked to null EntityEntry in persistence context : "
|
||||||
|
+ MessageHelper.infoString( entityPersister, pk, getFactory() )
|
||||||
|
);
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if ( !entry.requiresDirtyCheck( entity ) ) {
|
if ( !entry.requiresDirtyCheck( entity ) ) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -472,4 +472,58 @@ public void testQuerying() throws Exception {
|
|||||||
t.commit();
|
t.commit();
|
||||||
s.close();
|
s.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testClear() {
|
||||||
|
Session s = openSession();
|
||||||
|
s.beginTransaction();
|
||||||
|
User u = new User( "steve", "hb", "superSecret" );
|
||||||
|
s.persist( u );
|
||||||
|
s.getTransaction().commit();
|
||||||
|
s.close();
|
||||||
|
|
||||||
|
s = openSession();
|
||||||
|
s.beginTransaction();
|
||||||
|
u = (User) session.byNaturalId( User.class )
|
||||||
|
.using( "name", "steve" )
|
||||||
|
.using( "org", "hb" )
|
||||||
|
.load();
|
||||||
|
assertNotNull( u );
|
||||||
|
s.clear();
|
||||||
|
u = (User) session.byNaturalId( User.class )
|
||||||
|
.using( "name", "steve" )
|
||||||
|
.using( "org", "hb" )
|
||||||
|
.load();
|
||||||
|
assertNotNull( u );
|
||||||
|
s.delete( u );
|
||||||
|
s.getTransaction().commit();
|
||||||
|
s.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testEviction() {
|
||||||
|
Session s = openSession();
|
||||||
|
s.beginTransaction();
|
||||||
|
User u = new User( "steve", "hb", "superSecret" );
|
||||||
|
s.persist( u );
|
||||||
|
s.getTransaction().commit();
|
||||||
|
s.close();
|
||||||
|
|
||||||
|
s = openSession();
|
||||||
|
s.beginTransaction();
|
||||||
|
u = (User) session.byNaturalId( User.class )
|
||||||
|
.using( "name", "steve" )
|
||||||
|
.using( "org", "hb" )
|
||||||
|
.load();
|
||||||
|
assertNotNull( u );
|
||||||
|
s.evict( u );
|
||||||
|
u = (User) session.byNaturalId( User.class )
|
||||||
|
.using( "name", "steve" )
|
||||||
|
.using( "org", "hb" )
|
||||||
|
.load();
|
||||||
|
assertNotNull( u );
|
||||||
|
s.delete( u );
|
||||||
|
s.getTransaction().commit();
|
||||||
|
s.close();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user