HHH-12718 Test that dirtiness strategies are invoked a second time after a flush interceptor changes the entity state

Bytecode enhancement is harder to test, so I didn't add a test for that,
but since bytecode enhancement dirty checking is called exactly at the
same place, if one works, the other should, too.
This commit is contained in:
Yoann Rodière 2018-07-12 16:27:58 +02:00 committed by Guillaume Smet
parent c3c322d91b
commit a9f743069b
1 changed files with 63 additions and 1 deletions

View File

@ -6,14 +6,21 @@
*/
package org.hibernate.test.dirtiness;
import org.junit.Test;
import java.io.Serializable;
import org.hibernate.CustomEntityDirtinessStrategy;
import org.hibernate.EmptyInterceptor;
import org.hibernate.Session;
import org.hibernate.SessionBuilder;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.AvailableSettings;
import org.hibernate.cfg.Configuration;
import org.hibernate.persister.entity.EntityPersister;
import org.hibernate.type.Type;
import org.hibernate.testing.FailureExpected;
import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase;
import org.junit.Test;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
@ -68,6 +75,39 @@ public class CustomDirtinessStrategyTest extends BaseCoreFunctionalTestCase {
session.close();
}
@Test
@FailureExpected(jiraKey = "HHH-12718")
public void testCustomStrategyWithFlushInterceptor() {
Session session = openSession();
session.beginTransaction();
Long id = (Long) session.save( new Thing( INITIAL_NAME ) );
session.getTransaction().commit();
session.close();
Strategy.INSTANCE.resetState();
session = sessionWithInterceptor().openSession();
session.beginTransaction();
Thing thing = (Thing) session.get( Thing.class, id );
thing.setName( SUBSEQUENT_NAME );
session.getTransaction().commit();
session.close();
// As we used an interceptor, the custom strategy should have been called twice to find dirty properties
assertEquals( 1, Strategy.INSTANCE.canDirtyCheckCount );
assertEquals( 1, Strategy.INSTANCE.isDirtyCount );
assertEquals( 1, Strategy.INSTANCE.resetDirtyCount );
assertEquals( 2, Strategy.INSTANCE.findDirtyCount );
session = openSession();
session.beginTransaction();
thing = (Thing) session.get( Thing.class, id );
assertEquals( SUBSEQUENT_NAME, thing.getName() );
session.delete( thing );
session.getTransaction().commit();
session.close();
}
@Test
public void testOnlyCustomStrategyConsultedOnNonDirty() throws Exception {
Session session = openSession();
@ -97,6 +137,12 @@ public class CustomDirtinessStrategyTest extends BaseCoreFunctionalTestCase {
session.close();
}
private SessionBuilder sessionWithInterceptor() {
return sessionFactory().unwrap( SessionFactory.class )
.withOptions()
.interceptor( OnFlushDirtyInterceptor.INSTANCE );
}
public static class Strategy implements CustomEntityDirtinessStrategy {
public static final Strategy INSTANCE = new Strategy();
@ -151,4 +197,20 @@ public class CustomDirtinessStrategyTest extends BaseCoreFunctionalTestCase {
}
}
public static class OnFlushDirtyInterceptor extends EmptyInterceptor {
private static OnFlushDirtyInterceptor INSTANCE = new OnFlushDirtyInterceptor();
@Override
public boolean onFlushDirty(
Object entity,
Serializable id,
Object[] currentState,
Object[] previousState,
String[] propertyNames,
Type[] types) {
// Tell Hibernate ORM we did change the entity state, which should trigger another dirty check
return true;
}
}
}