diff --git a/persistence-modules/hibernate5/pom.xml b/persistence-modules/hibernate5/pom.xml index af94025a73..6b9a9abbe5 100644 --- a/persistence-modules/hibernate5/pom.xml +++ b/persistence-modules/hibernate5/pom.xml @@ -73,6 +73,11 @@ hibernate-jpamodelgen ${hibernate.version} + + io.dropwizard.metrics + metrics-core + ${dropwizard-metrics.version} + @@ -92,6 +97,7 @@ 1.4.196 3.8.0 2.9.7 + 4.0.5 diff --git a/persistence-modules/hibernate5/src/main/java/com/baeldung/hibernate/HibernateUtil.java b/persistence-modules/hibernate5/src/main/java/com/baeldung/hibernate/HibernateUtil.java index e0d1de591b..ea0af97d5a 100644 --- a/persistence-modules/hibernate5/src/main/java/com/baeldung/hibernate/HibernateUtil.java +++ b/persistence-modules/hibernate5/src/main/java/com/baeldung/hibernate/HibernateUtil.java @@ -68,6 +68,11 @@ public class HibernateUtil { return sessionFactory; } + public static SessionFactory getSessionFactoryByProperties(Properties properties) throws IOException { + ServiceRegistry serviceRegistry = configureServiceRegistry(properties); + return makeSessionFactory(serviceRegistry); + } + private static SessionFactory makeSessionFactory(ServiceRegistry serviceRegistry) { MetadataSources metadataSources = new MetadataSources(serviceRegistry); @@ -119,12 +124,15 @@ public class HibernateUtil { } private static ServiceRegistry configureServiceRegistry() throws IOException { - Properties properties = getProperties(); + return configureServiceRegistry(getProperties()); + } + + private static ServiceRegistry configureServiceRegistry(Properties properties) throws IOException { return new StandardServiceRegistryBuilder().applySettings(properties) .build(); } - private static Properties getProperties() throws IOException { + public static Properties getProperties() throws IOException { Properties properties = new Properties(); URL propertiesURL = Thread.currentThread() .getContextClassLoader() diff --git a/persistence-modules/hibernate5/src/test/java/com/baeldung/hibernate/queryplancache/QueryPlanCacheUnitTest.java b/persistence-modules/hibernate5/src/test/java/com/baeldung/hibernate/queryplancache/QueryPlanCacheUnitTest.java new file mode 100644 index 0000000000..68325c559f --- /dev/null +++ b/persistence-modules/hibernate5/src/test/java/com/baeldung/hibernate/queryplancache/QueryPlanCacheUnitTest.java @@ -0,0 +1,105 @@ +package com.baeldung.hibernate.queryplancache; + +import com.baeldung.hibernate.HibernateUtil; +import com.codahale.metrics.Timer; +import com.codahale.metrics.UniformReservoir; +import org.hibernate.Session; +import org.hibernate.SessionFactory; +import org.hibernate.jpa.QueryHints; +import org.hibernate.query.Query; +import org.junit.Ignore; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.Parameterized; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import java.util.Properties; +import java.util.concurrent.TimeUnit; + +@RunWith(Parameterized.class) +public class QueryPlanCacheUnitTest { + + private static final Logger LOGGER = LoggerFactory.getLogger(QueryPlanCacheUnitTest.class); + + @Parameterized.Parameters + public static List planCacheSize() { + List planCacheSizes = new ArrayList<>(); + + planCacheSizes.add(new Integer[]{1}); + planCacheSizes.add(new Integer[]{2}); + planCacheSizes.add(new Integer[]{3}); + + + return planCacheSizes; + } + + private Timer timer = new Timer(new UniformReservoir(9900)); + + private int planCacheSize; + + public QueryPlanCacheUnitTest(int planCacheSize) { + this.planCacheSize = planCacheSize; + } + + @Test + @Ignore + public void givenQueryPlanCacheSize_thenCompileQueries() throws IOException { + Session session = initSession(); + + //warm-up + for (int i = 0; i < 9900; i++) { + createFindEmployeesByDepartmentNameQuery(session); + createFindEmployeesByDesignationQuery(session); + createFindDepartmentOfAnEmployeeQuery(session); + } + + for (int i = 0; i < 3300; i++) { + long startTime = System.nanoTime(); + createFindEmployeesByDepartmentNameQuery(session); + timer.update(System.nanoTime() - startTime, TimeUnit.NANOSECONDS); + + startTime = System.nanoTime(); + createFindEmployeesByDesignationQuery(session); + timer.update(System.nanoTime() - startTime, TimeUnit.NANOSECONDS); + + startTime = System.nanoTime(); + createFindDepartmentOfAnEmployeeQuery(session); + timer.update(System.nanoTime() - startTime, TimeUnit.NANOSECONDS); + } + + LOGGER.info("Query Plan Cache Size - {}, Time(Nanoseconds) - {}", planCacheSize, timer.getSnapshot().get95thPercentile()); + + } + + private Session initSession() throws IOException { + Properties properties = HibernateUtil.getProperties(); + properties.put("hibernate.query.plan_cache_max_size", planCacheSize); + properties.put("hibernate.query.plan_parameter_metadata_max_size", planCacheSize); + SessionFactory sessionFactory = HibernateUtil.getSessionFactoryByProperties(properties); + return sessionFactory.openSession(); + } + + private Query createFindEmployeesByDepartmentNameQuery(Session session) { + return session.createQuery("SELECT e FROM DeptEmployee e " + + "JOIN e.department WHERE e.department.name = :deptName") + .setMaxResults(30) + .setHint(QueryHints.HINT_FETCH_SIZE, 30); + } + + private Query createFindEmployeesByDesignationQuery(Session session) { + return session.createQuery("SELECT e FROM DeptEmployee e " + + "WHERE e.title = :designation") + .setHint(QueryHints.SPEC_HINT_TIMEOUT, 1000); + } + + private Query createFindDepartmentOfAnEmployeeQuery(Session session) { + return session.createQuery("SELECT e.department FROM DeptEmployee e " + + "JOIN e.department WHERE e.employeeNumber = :empId"); + + } + +}