Problem
Often we write JPA Entity classes an have to ensure in a larger team that refactoring doesn’t create performance problems or logical errors in the entity model usual problems are:
- Missing fetch joins in Queries
- Which leads to slow fetch joins
- Wrong direction of Entity relations
- which leads to updates after inserts
- or even to deletes and reinserts of data
- Wrong transaction boundaries
- Which leads to multiple transactions for one logical business operation
@Component
public class HibernateAsserts {
private final Statistics statistics;
public HibernateAsserts(EntityManager entityManager) {
try (Session session = entityManager.unwrap(org.hibernate.Session.class)) {
@SuppressWarnings("resource")
SessionFactory factory = session.getSessionFactory();
factory.getStatistics().setStatisticsEnabled(true);
statistics = factory.getStatistics();
}
}
public HibernateAsserts assertTrxCount(int expected) {
long value = statistics.getTransactionCount();
if (value != expected) {
logSummary();
fail("Expected " + expected + " TransactionCount, but found " + value);
}
return this;
}
public HibernateAsserts assertInsertCount(int expected) {
long value = statistics.getEntityInsertCount();
if (value != expected) {
logSummary();
fail("Expected " + expected + " EntityInsertCount, but found " + value);
}
return this;
}
public void reset() {
statistics.clear();
}
public void logSummary() {
statistics.logSummary();
}
}In your test
@SpringBootTest
class MyTestClassTest {
@Autowired private SubjectUnderTest subject;
@Autowired private HibernateAsserts hibernateAsserts;
@Test
void textMyBusinessMethod() {
// GIVEN
// custom data setup for the test
// WHEN
hibernateAsserts.reset(); // ensure the setup is not in the stats
subject.runBusinessMethod();
// THEN
// any business asserts
hibernateAsserts
.assertTrxCount(1)
.assertInsertCount(1);
}
}