package org.hibernate.envers.test.performance;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.junit.Assert;
import org.junit.Test;
import org.hibernate.Session;
import org.hibernate.engine.spi.EntityEntry;
import org.hibernate.engine.spi.PersistenceContext;
import org.hibernate.engine.spi.SessionImplementor;
import org.hibernate.envers.enhanced.SequenceIdRevisionEntity;
import org.hibernate.envers.test.BaseEnversFunctionalTestCase;
import org.hibernate.envers.test.entities.StrTestEntity;
import org.hibernate.envers.test.entities.onetomany.SetRefEdEntity;
import org.hibernate.envers.test.entities.onetomany.SetRefIngEntity;
import org.hibernate.testing.TestForIssue;
/**
* @author Lukasz Antoniak (lukasz dot antoniak at gmail dot com)
*/
public class EvictAuditDataAfterCommitTest extends BaseEnversFunctionalTestCase {
@Override
protected Class<?>[] getAnnotatedClasses() {
return new Class[]{StrTestEntity.class, SetRefEdEntity.class, SetRefIngEntity.class};
}
@Test
@TestForIssue(jiraKey = "HHH-6614")
public void testSessionCacheClear() {
Session session = openSession();
session.getTransaction().begin();
StrTestEntity ste = new StrTestEntity("data");
session.persist(ste);
session.getTransaction().commit();
checkEmptyAuditSessionCache(session, "org.hibernate.envers.test.entities.StrTestEntity_AUD");
}
@Test
@TestForIssue(jiraKey = "HHH-6614")
public void testSessionCacheCollectionClear() {
final String[] auditEntityNames = new String[] {"org.hibernate.envers.test.entities.onetomany.SetRefEdEntity_AUD",
"org.hibernate.envers.test.entities.onetomany.SetRefIngEntity_AUD"};
SetRefEdEntity ed1 = new SetRefEdEntity(1, "data_ed_1");
SetRefEdEntity ed2 = new SetRefEdEntity(2, "data_ed_2");
SetRefIngEntity ing1 = new SetRefIngEntity(3, "data_ing_1");
SetRefIngEntity ing2 = new SetRefIngEntity(4, "data_ing_2");
Session session = openSession();
session.getTransaction().begin();
session.persist(ed1);
session.persist(ed2);
session.persist(ing1);
session.persist(ing2);
session.getTransaction().commit();
checkEmptyAuditSessionCache(session, auditEntityNames);
session.getTransaction().begin();
ed1 = (SetRefEdEntity) session.load(SetRefEdEntity.class, ed1.getId());
ing1.setReference(ed1);
ing2.setReference(ed1);
session.getTransaction().commit();
checkEmptyAuditSessionCache(session, auditEntityNames);
session.getTransaction().begin();
ed2 = (SetRefEdEntity) session.load(SetRefEdEntity.class, ed2.getId());
Set<SetRefIngEntity> reffering = new HashSet<SetRefIngEntity>();
reffering.add(ing1);
reffering.add(ing2);
ed2.setReffering(reffering);
session.getTransaction().commit();
checkEmptyAuditSessionCache(session, auditEntityNames);
session.getTransaction().begin();
ed2 = (SetRefEdEntity) session.load(SetRefEdEntity.class, ed2.getId());
ed2.getReffering().remove(ing1);
session.getTransaction().commit();
checkEmptyAuditSessionCache(session, auditEntityNames);
session.getTransaction().begin();
ed2 = (SetRefEdEntity) session.load(SetRefEdEntity.class, ed2.getId());
ed2.getReffering().iterator().next().setData("mod_data_ing_2");
session.getTransaction().commit();
checkEmptyAuditSessionCache(session, auditEntityNames);
session.close();
}
private void checkEmptyAuditSessionCache(Session session, String ... auditEntityNames) {
List<String> entityNames = Arrays.asList(auditEntityNames);
PersistenceContext persistenceContext = ((SessionImplementor) session).getPersistenceContext();
for (Object entry : persistenceContext.getEntityEntries().values()) {
EntityEntry entityEntry = (EntityEntry) entry;
if (entityNames.contains(entityEntry.getEntityName())) {
assert false : "Audit data shall not be stored in the session level cache. This causes performance issues.";
}
Assert.assertFalse("Revision entity shall not be stored in the session level cache. This causes performance issues.",
SequenceIdRevisionEntity.class.getName().equals(entityEntry.getEntityName()));
}
}
}