JPA Model testing with Hibernate Statistics

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);
  }
}

Paul Sterl has written 54 articles

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>