diff --git a/persistence-modules/hibernate5/pom.xml b/persistence-modules/hibernate5/pom.xml
index af94025a73..a09669c8b5 100644
--- a/persistence-modules/hibernate5/pom.xml
+++ b/persistence-modules/hibernate5/pom.xml
@@ -73,6 +73,16 @@
hibernate-jpamodelgen
${hibernate.version}
+
+ org.openjdk.jmh
+ jmh-core
+ ${openjdk-jmh.version}
+
+
+ org.openjdk.jmh
+ jmh-generator-annprocess
+ ${openjdk-jmh.version}
+
@@ -92,6 +102,7 @@
1.4.196
3.8.0
2.9.7
+ 1.21
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/QueryPlanCacheBenchmark.java b/persistence-modules/hibernate5/src/test/java/com/baeldung/hibernate/queryplancache/QueryPlanCacheBenchmark.java
new file mode 100644
index 0000000000..13eae3d877
--- /dev/null
+++ b/persistence-modules/hibernate5/src/test/java/com/baeldung/hibernate/queryplancache/QueryPlanCacheBenchmark.java
@@ -0,0 +1,106 @@
+package com.baeldung.hibernate.queryplancache;
+
+import com.baeldung.hibernate.HibernateUtil;
+import org.hibernate.Session;
+import org.hibernate.SessionFactory;
+import org.hibernate.jpa.QueryHints;
+import org.hibernate.query.Query;
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Fork;
+import org.openjdk.jmh.annotations.Measurement;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Param;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+import org.openjdk.jmh.annotations.TearDown;
+import org.openjdk.jmh.annotations.Warmup;
+import org.openjdk.jmh.infra.Blackhole;
+import org.openjdk.jmh.runner.RunnerException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.IOException;
+import java.util.Properties;
+import java.util.concurrent.TimeUnit;
+
+public class QueryPlanCacheBenchmark {
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(QueryPlanCacheBenchmark.class);
+
+ @State(Scope.Thread)
+ public static class QueryPlanCacheBenchMarkState {
+ @Param({"1", "2", "3"})
+ public int planCacheSize;
+
+ public Session session;
+
+ @Setup
+ public void stateSetup() throws IOException {
+ LOGGER.info("State - Setup");
+ session = initSession(planCacheSize);
+ LOGGER.info("State - Setup Complete");
+ }
+
+ private Session initSession(int planCacheSize) 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();
+ }
+
+ @TearDown
+ public void tearDownState() {
+ LOGGER.info("State - Teardown");
+ SessionFactory sessionFactory = session.getSessionFactory();
+ session.close();
+ sessionFactory.close();
+ LOGGER.info("State - Teardown complete");
+ }
+ }
+
+ @Benchmark
+ @BenchmarkMode(Mode.AverageTime)
+ @OutputTimeUnit(TimeUnit.MICROSECONDS)
+ @Fork(1)
+ @Warmup(iterations = 2)
+ @Measurement(iterations = 5)
+ public void givenQueryPlanCacheSize_thenCompileQueries(QueryPlanCacheBenchMarkState state, Blackhole blackhole) {
+
+ Query query1 = findEmployeesByDepartmentNameQuery(state.session);
+ Query query2 = findEmployeesByDesignationQuery(state.session);
+ Query query3 = findDepartmentOfAnEmployeeQuery(state.session);
+
+ blackhole.consume(query1);
+ blackhole.consume(query2);
+ blackhole.consume(query3);
+
+ }
+
+ private Query findEmployeesByDepartmentNameQuery(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 findEmployeesByDesignationQuery(Session session) {
+ return session.createQuery("SELECT e FROM DeptEmployee e " +
+ "WHERE e.title = :designation")
+ .setHint(QueryHints.SPEC_HINT_TIMEOUT, 1000);
+ }
+
+ private Query findDepartmentOfAnEmployeeQuery(Session session) {
+ return session.createQuery("SELECT e.department FROM DeptEmployee e " +
+ "JOIN e.department WHERE e.employeeNumber = :empId");
+
+ }
+
+ public static void main(String... args) throws IOException, RunnerException {
+ //main-class to run the benchmark
+ org.openjdk.jmh.Main.main(args);
+ }
+}