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