Hypersistence Optimizer Installation Guide

Table of Contents

Introduction

Hypersistence Optimizer is a dynamic analyzing tool that can scan your JPA and Hibernate application and provide you tips about the changes you need to make to entity mappings, configurations, queries, and Persistence Context actions to speed up your data access layer.

Once you have downloaded the Full or Trial version, you need to follow a series of steps in order to install Hypersistence Optimizer.

Step 1: Unzip the package

The first thing you need to do is to unzip the package you have just downloaded.

unzip hypersistence-optimizer-2.8.2-pack.zip

After unzipping the project package, you will get the following file structure:

creating: hypersistence-optimizer-2.8.2/
   creating: hypersistence-optimizer-2.8.2/lib/
  inflating: hypersistence-optimizer-2.8.2/lib/hypersistence-optimizer-2.8.2-javadoc.jar
  inflating: hypersistence-optimizer-2.8.2/lib/hypersistence-optimizer-2.8.2-sources.jar
  inflating: hypersistence-optimizer-2.8.2/lib/hypersistence-optimizer-2.8.2.jar
  inflating: hypersistence-optimizer-2.8.2/lib/hypersistence-optimizer-2.8.2-jre6-javadoc.jar
  inflating: hypersistence-optimizer-2.8.2/lib/hypersistence-optimizer-2.8.2-jre6-sources.jar
  inflating: hypersistence-optimizer-2.8.2/lib/hypersistence-optimizer-2.8.2-jre6.jar
  inflating: hypersistence-optimizer-2.8.2/lib/hypersistence-optimizer-2.8.2-jakarta-javadoc.jar
  inflating: hypersistence-optimizer-2.8.2/lib/hypersistence-optimizer-2.8.2-jakarta-sources.jar
  inflating: hypersistence-optimizer-2.8.2/lib/hypersistence-optimizer-2.8.2-jakarta.jar
   creating: hypersistence-optimizer-2.8.2/docs/
   creating: hypersistence-optimizer-2.8.2/docs/html/
   creating: hypersistence-optimizer-2.8.2/docs/pdf/
  inflating: hypersistence-optimizer-2.8.2/docs/html/asciidoctor.css
  inflating: hypersistence-optimizer-2.8.2/docs/html/coderay-asciidoctor.css
  inflating: hypersistence-optimizer-2.8.2/docs/pdf/InstallationGuide.pdf
  inflating: hypersistence-optimizer-2.8.2/docs/html/InstallationGuide.html
  inflating: hypersistence-optimizer-2.8.2/docs/html/UserGuide.html
  inflating: hypersistence-optimizer-2.8.2/docs/pdf/UserGuide.pdf
  inflating: hypersistence-optimizer-2.8.2/changelog.txt
  inflating: hypersistence-optimizer-2.8.2/LICENSE.txt
  inflating: hypersistence-optimizer-2.8.2/archiva-deploy.bat
  inflating: hypersistence-optimizer-2.8.2/archiva-deploy.sh
  inflating: hypersistence-optimizer-2.8.2/maven-install.bat
  inflating: hypersistence-optimizer-2.8.2/maven-install.sh
  inflating: hypersistence-optimizer-2.8.2/README.txt

The package contains the following resources:

  • the lib folder contains the main jar file, as well as the JavaDoc and the Java sources
  • the docs folder contains the Installation and User Guides
  • the changelog file contains the release notes for all product versions
  • the LICENSE file contains the project license info
  • the maven-install scripts allow you to install the Java artifacts in your local Maven repository
  • the README file contains a short description of the project

Note that the documentation folder is not available in the Trial version. For the Trail version, you can use the online documentation only.

Step 2: Installing the Maven dependency

Whether you are using Maven or Gradle, you need to install the Maven dependency to your local repository.

For Windows, use the maven-install.bat script:

maven-install.bat

For Unix-based systems (e.g., Linux, Mac OS), use the maven-install.sh script:

./maven-install.sh

Now, the hypersistence-optimizer Maven dependency is installed in your local repository.

Installing the Maven dependency using a public or private Maven repository

If you have a group license and want to share it with your team, then you have two options:

  • The first and most convenient option is to use the public Hypersistence Maven Repository. If you want to use this option, then please contact support so that we can register you an account on the public repository.
  • The second option is to use a private Maven repository, like Apache Archiva or JFrog Artifactory.

Installing the Maven dependency on Apache Archiva (Optional Step)

The following Apache Archiva installation step is optional, so only consider it if you plan on sharing your Hypersistence Optimizer library with your team because you purchased a group license and don’t want to use the public Hypersistence repository that we can provide you access to.

If you haven’t yet installed Apache Archiva, you can either use this guide or by following these steps.

After downloading the latest version, you need to unzip it, go to the bin folder, and run the following two commands:

archiva install
archiva start

After running these commands, Archiva will start a web application, which, by default, can be accessed at the localhost:8080 address. You need to access this address and create an admin user.

Afterward, you need to navigate to the Maven M2_HOME folder and configure the settings.xml configuration file so that you add the following two server XML tags in the servers parent tag:

<servers>
    <server>
        <id>archiva.internal</id>
        <username>admin</username>
        <password>${archiva-admin-password}</password>
    </server>
    <server>
        <id>archiva.snapshots</id>
        <username>admin</username>
        <password>${archiva-admin-password}</password>
    </server>
</servers>

Note that you need to replace the ${archiva-admin-password} placeholders with the Archiva admin user password that you set previously.

Afterward, you can use the archiva-deploy scripts provided in the project pack:

For Windows, use the archiva-deploy.bat script:

archiva-deploy.bat http://localhost:8080/repository/internal/ archiva.internal

For Unix-based systems (e.g., Linux, Mac OS), use the archiva-deploy.sh script:

./archiva-deploy.sh http://localhost:8080/repository/internal/ archiva.internal

Note that the archiva-deploy script takes two arguments:

  • The first argument is the URL where the Apache Archiva repository is located (e.g., `http://localhost:8080/repository/internal/`).
  • The second argument is the Apache Archiva repository id where the artifacts are to be deployed (e.g., archiva.internal).

Now, you need to go to the main pom.xml Maven configuration file of your project and add the Apache Archiva repository:

<repositories>
    <repository>
        <id>archiva.internal</id>
        <name>Archiva 3rd-party Artifact Repository</name>
        <url>http://localhost:8080/repository/internal/</url>
    </repository>
</repositories>

<properties>
    <archiva-repository-id>archiva.internal</archiva-repository-id>
    <archiva-repository-url>http://localhost:8080/repository/internal/</archiva-repository-url>
</properties>

Note that you need to change the archiva-repository-id and archiva-repository-url properties to match your Apache Archiva repository settings.

Step 3: Adding the dependency to your project

Now, you need to add the hypersistence-optimizer dependency to your project.

Step 3.1: Adding the dependency using Maven

If you are using Maven, then you need to add the following dependency tag to your pom.xml configuration file:

<dependency>
    <groupId>io.hypersistence</groupId>
    <artifactId>hypersistence-optimizer</artifactId>
    <version>${hypersistence-optimizer.version}</version>
</dependency>

The ${hypersistence-optimizer.version} is a Maven property that you need to declare in the properties tag of your pom.xml configuration file like this:


    ...
    2.8.2

Step 3.1.1: Add all-open if you’re using Kotlin with Maven

When using Kotlin, you need to use the all-open compiler plugin.

First, you will need to add the kotlin-maven-allopen dependency:


    org.jetbrains.kotlin
    kotlin-maven-allopen
    ${kotlin.version}

Second, you need to configure the kotlin-maven-plugin to use the all-open compiler plugin:


    org.jetbrains.kotlin
    kotlin-maven-plugin
    ${kotlin.version}
    
        
            ...
            all-open
        
        
            
            
            
        
    
    
        
            compile
            
                compile
            
            
                
                    ${project.basedir}/src/main/kotlin
                    ${project.basedir}/src/main/java
                
            
        
        
            test-compile
            
                test-compile
            
            
                
                    ${project.basedir}/src/test/kotlin
                    ${project.basedir}/src/test/java
                
            
        
    

If you’re using Jakarta Persistence, you will need to replace the javax.persistence entries in the option XML elements with jakarta.persistence.

Step 3.2: Adding the dependency using Gradle

If you’re using Gradle, then you should add the following dependency:

dependencies {
    ...
    implementation "io.hypersistence:hypersistence-optimizer:${hypersistenceOptimizerVersion}"
}

The ${hypersistenceOptimizerVersion} is a Gradle property which you need to declare in the ext block:

ext {
    ...
    hypersistenceOptimizerVersion = '2.8.2'
}

Also, when using Gradle, make sure that you add the mavenLocal() to your build.gradle configuration file.

repositories {
    mavenCentral()
    mavenLocal()
}

Step 3.2.1: Add all-open if you’re using Kotlin with Gradle

If you are using Kotlin, you need to use the all-open compiler plugin.

This can be done as follows:

buildscript {
    dependencies {
        classpath "org.jetbrains.kotlin:kotlin-allopen:$kotlin_version"
    }
}

apply plugin: "kotlin-allopen"

allOpen {
    annotations(
        "javax.persistence.Entity", 
        "javax.persistence.MappedSuperclass", 
        "javax.persistence.Embedabble"
    )
}

If you’re using Jakarta Persistence, you will need to replace the javax.persistence entries that are passed to the annotations method with their jakarta.persistence counterparts.

Jakarta Persistence

Therefore, from Hibernate 6 onwards, you should use the jakarta classifier when declaring the Hypersistence Optimizer dependency.

For Maven, the classifier XML tag of the hypersistence-optimizer dependency must be set like this:


    io.hypersistence
    hypersistence-optimizer
    2.8.2
    jakarta

Java 6 and 7

If your application is running on Java 6 or 7, you should use the jre6 classifier.

Therefore, for Maven, the classifier XML tag of the hypersistence-optimizer dependency must be set like this:


    io.hypersistence
    hypersistence-optimizer
    2.8.2
    jre6

Trial Version

If you’re using the Trial Version, then your dependency should end with the trial suffix.

For Maven, the version XML tag of the hypersistence-optimizer dependency must be set like this:


    io.hypersistence
    hypersistence-optimizer
    2.6.0-trial

You can use this GitHub branch for the trial version as it provides various Spring or Java EE examples that you can use with Trial Version to verify how the tool works.

Step 4: Logging settings

By default, all events are logged using the Hypersistence Optimizer logger name. Based on the performance optimization event priority, Hypersistence Optimizer will trigger either an ERROR, WARN, or INFO log message. For this reason, it’s best to enable the INFO log level for the Hypersistence Optimizer logger name.

Logback logging setting

If you’re using Logback, you need to add the following logger entry to the Logback XML configuration file:


Log4j 2 logging setting

If you’re using Log4j 2, you need to add the following logger entry to the Log4j 2 configuration file:


Notice that the appender-ref XML element used the Console appender. You need to change that to whatever appender or appenders you have defined in your log configuration file.

Log4j 1.x logging setting

If you’re using Log4j 1.x, you need to add the following logger entry to the log4j.properties file:

log4j.category.Hypersistence\ Optimizer=INFO

Step 5: Decorating the Persistence Unit

While scanning the Persistence Unit (e.g., EntityManagerFactory or SessionFactory) metadata only requires access to the existing JPA EntityManagerFactory or Hibernate SessionFactory, to inspect the Persistence Context and the currently executing queries, Hypersistence Optimizer needs to decorate the JPA EntityManagerFactory or Hibernate SessionFactory and inject various performance-related checks at runtime.

Depending on the Hibernate version you are using, there are different ways you can decorate the JPA Persistence Unit.

To determine the Hibernate version your application is using, you can run the mvn dependency:tree command.

For instance, when running the mvn dependency:tree command in the root folder of this Spring Boot PetClinic GitHub fork:

mvn dependency:tree

You will notice that the Hibernate ORM 5.3.9 version is used:

+- org.springframework.boot:spring-boot-starter-data-jpa:jar:2.1.4.RELEASE:compile
|  +- org.hibernate:hibernate-core:jar:5.3.9.Final:compile

Once you know the Hibernate version you are using, you can proceed to decorate the JPA and Hibernate Persistence Unit.

Decorating the Persistence Unit using Hibernate 5

If you’re using Hibernate 5, you don’t need to do anything since the Hibernate SessionFactory (even when using JPA with Hibernate),
is decorated automatically by the org.hibernate.boot.spi.SessionFactoryBuilderFactory service loader mechanism.

The overhead added by the Hibernate SessionFactoryDecorator is minimal. Because method calls are inlined, many runtime proxies used by frameworks like Spring or connection pools have a higher overhead than the approach taken by the SessionFactoryDecorator.

If you want to disable the SessionFactory decoration process, then you have to set the following configuration property in an application.properties or hibernate.properties file:

  hypersistence.enable_auto_session_factory_decoration=false
  

You can also provide this property as a Java System property when starting your application.

Setting the LocalSessionFactoryBean asynchronous bootstrap executor

If you are configuring a SimpleAsyncTaskExecutor via the bootstrapExecutor property of the LocalSessionFactoryBean via the Java-based configuration:

@Bean
public LocalSessionFactoryBean sessionFactory() {
    LocalSessionFactoryBean localSessionFactoryBean = new LocalSessionFactoryBean();
    ...
    localSessionFactoryBean.setBootstrapExecutor(new SimpleAsyncTaskExecutor());
    return localSessionFactoryBean;
}

or XML configuration:


    ...
    
        
    

Then, Spring will use a Proxy when creating the SessionFactory, which can cause issues when binding and referencing the current transaction context.

So, to avoid this kind of issue, you need to change the sessionFactory definition, as follows.

For Java-based configuration, use this SessionFactory definition:

@Bean
public LocalSessionFactoryBean originalSessionFactory() {
    LocalSessionFactoryBean localSessionFactoryBean = new LocalSessionFactoryBean();
    ...
    localSessionFactoryBean.setBootstrapExecutor(new SimpleAsyncTaskExecutor());
    return localSessionFactoryBean;
}
 
@Bean
@Primary
public SessionFactory sessionFactory(SessionFactory originalSessionFactory) {
    if(originalSessionFactory instanceof InfrastructureProxy) {
        InfrastructureProxy infrastructureProxy = (InfrastructureProxy) originalSessionFactory;
        return (SessionFactory) infrastructureProxy.getWrappedObject();
    }
    return originalSessionFactory;
}

And, for XML configuration, use this SessionFactory definition instead:


    ...
    
        
    




You can find a working example using the above configuration in the hypersistence-optimizer-spring-hibernate-example GitHub repository.

Decorating the Persistence Unit using Hibernate 4 and 3

Since the SessionFactoryBuilderFactory mechanism was introduced in Hibernate 5, if you’re using Hibernate 4 or 3, you will need to decorate the JPA EntityManagerFactory or the Hibernate SessionFactory manually, as illustrated by the following configurations.

Decorating the Persistence Unit using Spring

If you’re using Spring, you can use either the Java-based configuration or the legacy XML configuration files. The following configuration examples will show you how to decorate the Persistence Unit manually using Spring when using either Hibernate 4 or 3.

Decorating the Persistence Unit using Spring and Hibernate 4

If you’re using Hibernate 4, then the Persistence Unit can be created either via a LocalSessionFactoryBean or the LocalContainerEntityManagerFactoryBean.

Decorating the Hibernate 4 SessionFactory programmatically with Spring Java-based configuration

To decorate the Hibernate SessionFactory, you just need to pass the SessionFactory reference to the decorate method of the HypersistenceHibernatePersistenceProvider class. For this reason, the LocalSessionFactoryBean creates a bean, called originalSessionFactory.

This is the bean you would have normally named sessionFactory, but, in this case, it needs to have a different name as the sessionFactory bean name is reserved for the Hypersistence Optimizer SessionFactory, as illustrated by the following configuration:

@Bean
public LocalSessionFactoryBean originalSessionFactory() {
    LocalSessionFactoryBean localSessionFactoryBean =
        new LocalSessionFactoryBean();
    localSessionFactoryBean.setDataSource(dataSource());
    localSessionFactoryBean.setPackagesToScan(packagesToScan());
    localSessionFactoryBean.setHibernateProperties(additionalProperties());
    return localSessionFactoryBean;
}
 
@Bean
@Primary
public SessionFactory sessionFactory(
        SessionFactory originalSessionFactory) {
    return HypersistenceHibernatePersistenceProvider.decorate(
        originalSessionFactory
    );
}

First, we create the LocalSessionFactoryBean, which will be used to create a SessionFactory that’s decorated by the HypersistenceHibernatePersistenceProvider class.

Notice that we used the @Primary annotation on the decorated sessionFactory bean method to instruct Spring that this bean should be used whenever a SessionFactory dependency is needed.

You can find a working example using the above configuration in the hypersistence-optimizer-spring-hibernate4-example GitHub repository.

Decorating the Hibernate 4 SessionFactory declaratively with Spring XML configuration

To decorate the Hibernate SessionFactory using the legacy XML configuration, you just need to wrap the original SessionFactory as illustrated by the following examples.


    
    
         
           ${packages.to.scan}
         
    
    
        
            ${hibernate.dialect}
            ${hibernate.hbm2ddl.auto}
        
    



    

First, we create the LocalSessionFactoryBean, which will be used to create a SessionFactory that’s decorated by the HypersistenceHibernatePersistenceProvider class.

Notice that we set the primary attribute to true on the decorated sessionFactory bean configuration to instruct Spring that this bean should be used whenever a SessionFactory dependency is needed.

You can find a working example using the above configuration in the hypersistence-optimizer-spring-hibernate4-example GitHub repository.

Decorating the Hibernate 4 JPA EntityManagerFactory programmatically with Spring Java-based configuration

To decorate the JPA EntityManagerFactory, you just need to pass the EntityManagerFactory reference to the decorate method of the HypersistenceHibernatePersistenceProvider class:

@Bean
public LocalContainerEntityManagerFactoryBean entityManagerFactoryBean() {
    LocalContainerEntityManagerFactoryBean entityManagerFactoryBean =
        new LocalContainerEntityManagerFactoryBean();
    entityManagerFactoryBean.setPersistenceUnitName(persistenceUnitName());
    entityManagerFactoryBean.setPersistenceProvider(new HibernatePersistenceProvider());
    entityManagerFactoryBean.setDataSource(dataSource());
    entityManagerFactoryBean.setPackagesToScan(packagesToScan());
 
    JpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
    entityManagerFactoryBean.setJpaVendorAdapter(vendorAdapter);
    entityManagerFactoryBean.setJpaProperties(additionalProperties());
 
    return entityManagerFactoryBean;
}

@Bean
@Primary
public EntityManagerFactory entityManagerFactory(
        LocalContainerEntityManagerFactoryBean entityManagerFactoryBean) {
    return HypersistenceHibernatePersistenceProvider.decorate(
        entityManagerFactoryBean.getNativeEntityManagerFactory()
    );
}

First, we create the LocalContainerEntityManagerFactoryBean, which will be used to create an EntityManagerFactory that’s decorated by the HypersistenceHibernatePersistenceProvider class.

Notice that we used the @Primary annotation on the decorated entityManagerFactory bean method to instruct Spring that this bean should be used whenever an EntityManagerFactory dependency is needed.

You can find a working example using the above configuration in the hypersistence-optimizer-spring-jpa-hibernate4-example GitHub repository.

Decorating the Hibernate 4 JPA EntityManagerFactory declaratively with Spring XML configuration

To decorate the JPA EntityManagerFactory using the legacy XML configuration, you just need to wrap the original EntityManagerFactory as illustrated by the following examples.


    
        
            
            
                
                    ${packages.to.scan}
                
            
            
            
                
                    ${hibernate.dialect}
                    ${hibernate.hbm2ddl.auto}
                
            
        
    

Notice that we haven’t defined a LocalContainerEntityManagerFactoryBean bean that will be decorated by the primary entityManagerFactory, as we did for the Java-based configuration.

This time, we are just passing the LocalContainerEntityManagerFactoryBean to the decorate method of the HypersistenceHibernatePersistenceProvider utility in order to create the EntityManagerFactory bean.

You can find a working example using the above configuration in the hypersistence-optimizer-spring-hibernate4-example GitHub repository.

Decorating the Persistence Unit using Spring and Hibernate 3

If you’re using Hibernate 3, then the Persistence Unit can be created either via an AnnotationSessionFactoryBean or the LocalContainerEntityManagerFactoryBean.

Decorating the Hibernate 3 SessionFactory programmatically with Spring Java-based configuration

To decorate the Hibernate SessionFactory, you just need to pass the SessionFactory reference to the decorate method of the HypersistenceHibernatePersistenceProvider class.
For this reason, the AnnotationSessionFactoryBean creates a bean, called originalSessionFactory.

This is the bean you would have normally named sessionFactory, but, in this case, it needs to have a different name as the sessionFactory bean name is reserved for the Hypersistence Optimizer SessionFactory, as illustrated by the following configuration:

@Bean
public AnnotationSessionFactoryBean originalSessionFactory() {
    AnnotationSessionFactoryBean localSessionFactoryBean = new AnnotationSessionFactoryBean();
    localSessionFactoryBean.setDataSource(dataSource());
    localSessionFactoryBean.setPackagesToScan(packagesToScan());
    localSessionFactoryBean.setHibernateProperties(additionalProperties());
    return localSessionFactoryBean;
}
 
@Bean
public SessionFactory sessionFactory(SessionFactory originalSessionFactory) {
    return HypersistenceHibernatePersistenceProvider.decorate(
        originalSessionFactory
    );
}

You can find a working example using the above configuration in the hypersistence-optimizer-spring-hibernate3-example GitHub repository.

Decorating the Hibernate 3 SessionFactory with Spring XML configuration

If you’re using Hibernate 3, you can use the following XML configuration to decorate the Hibernate SessionFactory:


    
    
         
           ${packages.to.scan}
         
    
    
        
            ${hibernate.dialect}
            ${hibernate.hbm2ddl.auto}
        
    



    

You can find a working example using the above configuration in the hypersistence-optimizer-spring-hibernate3-example GitHub repository.

Decorating the Hibernate 3 JPA EntityManagerFactory programmatically with Spring Java-based configuration

To decorate the JPA EntityManagerFactory, you just need to pass the EntityManagerFactory reference to the decorate method of the HypersistenceHibernatePersistenceProvider class:

@Bean
public EntityManagerFactory entityManagerFactory() {
    LocalContainerEntityManagerFactoryBean entityManagerFactoryBean =
        new LocalContainerEntityManagerFactoryBean();
    entityManagerFactoryBean.setPersistenceUnitName(persistenceUnitName());
    entityManagerFactoryBean.setPersistenceProvider(new HibernatePersistence());
    entityManagerFactoryBean.setDataSource(dataSource());
    entityManagerFactoryBean.setPackagesToScan(packagesToScan());
 
    JpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
    entityManagerFactoryBean.setJpaVendorAdapter(vendorAdapter);
    entityManagerFactoryBean.setJpaProperties(additionalProperties());
 
    entityManagerFactoryBean.afterPropertiesSet();
 
    return HypersistenceHibernatePersistenceProvider.decorate(
        entityManagerFactoryBean.getNativeEntityManagerFactory()
    );
}

To avoid creating two different beans of the EntityManagerFactory type, that will prevent you from using the @PersistenceUnit application without an explicit name qualifier, you can create the LocalContainerEntityManagerFactoryBean and initialize it by calling afterPropertiesSet prior to passing the resulting EntityManagerFactory to the decorate method.

You can find a working example using the above configuration in the hypersistence-optimizer-spring-jpa-hibernate3-example GitHub repository.

Decorating the Hibernate 3 JPA EntityManagerFactory declaratively with Spring XML configuration

To decorate the JPA EntityManagerFactory using the legacy XML configuration,
you just need to wrap the original EntityManagerFactory as illustrated by the following examples.


    
        
            
            
                
                    ${packages.to.scan}
                
            
            
            
                
                    ${hibernate.dialect}
                    ${hibernate.hbm2ddl.auto}
                
            
        
    

Notice that we are just passing the LocalContainerEntityManagerFactoryBean to the decorate method of the
HypersistenceHibernatePersistenceProvider utility in order to create the EntityManagerFactory bean.

You can find a working example using the above configuration in the hypersistence-optimizer-spring-jpa-hibernate3-example GitHub repository.

Decorating the JPA EntityManagerFactory declaratively

To decorate the JPA EntityManagerFactory declaratively using the persistence.xml configuration file, you need to use the HypersistenceHibernatePersistenceProvider class, as illustrated by the provider XML tag in the following example:




    

        io.hypersistence.optimizer.hibernate.decorator.HypersistenceHibernatePersistenceProvider

        java:global/jdbc/default

        
            

            

            

            
        
    

You can find a working example using the above configuration in the hypersistence-optimizer-glassfish-hibernate4-example GitHub repository.

Step 6: Instantiating HypersistenceOptimizer

Depending on your project environment, there are different ways you can instantiate the HypersistenceOptimizer object, which is the main class of the Hypersistence Optimizer framework.

Spring Boot configuration

If you’re using Spring Boot, then you can instantiate the HypersistenceOptimizer object like this:

@Configuration
public class HypersistenceConfiguration {
    @Bean
    public HypersistenceOptimizer hypersistenceOptimizer(
            EntityManagerFactory entityManagerFactory) {
        return new HypersistenceOptimizer(
            new JpaConfig(entityManagerFactory)
        );
    }
}

Afterward, you can inject the HypersistenceOptimizer dependency in your integration tests:

@RunWith(SpringRunner.class)
@DataJpaTest
public class ApplicationTest {
    @Autowired
    private HypersistenceOptimizer hypersistenceOptimizer;
 
    @Test
    public void test() {
        assertTrue(hypersistenceOptimizer.getEvents().isEmpty());
    }
}

The hypersistence-optimizer-spring-boot-example GitHub project demonstrates how you can use Hypersistence Optimizer in a Spring Boot project.

Spring and JPA configuration

If you’re using Hibernate via JPA, you can instantiate the HypersistenceOptimizer object like this:

@Bean
public HypersistenceOptimizer hypersistenceOptimizer(
        EntityManagerFactory entityManagerFactory) {
    return new HypersistenceOptimizer(
        new JpaConfig(entityManagerFactory)
    );
}

The hypersistence-optimizer-spring-jpa-example GitHub project demonstrates how you can use Hypersistence Optimizer in a Spring JPA project.

Spring and Hibernate configuration

If you’re using Hibernate via the native API, then you can instantiate the HypersistenceOptimizer object like this:

@Bean
public HypersistenceOptimizer hypersistenceOptimizer(
        SessionFactory sessionFactory) {
    return new HypersistenceOptimizer(
        new HibernateConfig(sessionFactory)
    );
}

The hypersistence-optimizer-spring-hibernate-example GitHub project demonstrates how you can use Hypersistence Optimizer in a Spring Hibernate project.

Java EE configuration

If you’re using Java EE, you can instantiate the hypersistenceOptimizer object in an Arquillian Integration Test, as follows:

@PersistenceUnit
private EntityManagerFactory entityManagerFactory;
 
private HypersistenceOptimizer hypersistenceOptimizer;
 
@Before
public void init() {
    hypersistenceOptimizer = new HypersistenceOptimizer(
        new JpaConfig(
            getEntityManagerFactory()
        )
    );
}

The hypersistence-optimizer-glassfish-hibernate-example GitHub repository demonstrates how you can use Hypersistence Optimizer in a Java EE project.

Grails configuration

If you’re using Grails, then you can get the reference to the underlying SessionFactory and use it to build the HibernateConfig instance.

With the HibernateConfig object in place, you can instantiate the HypersistenceOptimizer object, as illustrated by the following example:

class PetclinicService {
 
    def sessionFactory
 
    def hypersistenceOptimizer
 
    @PostConstruct
    void init() {
        hypersistenceOptimizer = new HypersistenceOptimizer(
            new HibernateConfig(sessionFactory)
        )
    }
 
    ... 
}

Because the Grails DomainClassUnitTestMixin uses the SimpleMapDatastore, and not the HibernateDatastore, you won’t be able to integrate Hypersistence Optimizer with tests that use the DomainClassUnitTestMixin.

So, to see the Hypersistence Optimizer events, you should start the Grails Application instead and check out the logs for the optimization events.

This GitHub repository demonstrates how you can use Hypersistence Optimizer in a Grails project.

Play Framework configuration

If you’re using Play Framework, you can get the reference to the default EntityManagerFactory via reflection from the JPAApi object reference.

Once you get the EntityManagerFactory object reference, you can use it to build the JpaConfig and instantiate the HypersistenceOptimizer object, like this:

public class PostRepositoryImpl implements PostRepository {
 
    private final JPAApi jpaApi;
 
    private final DatabaseExecutionContext executionContext;
 
    private final HypersistenceOptimizer hypersistenceOptimizer;
 
    @Inject
    public PostRepositoryImpl(
            JPAApi jpaApi, 
            DatabaseExecutionContext executionContext) {
        this.jpaApi = jpaApi;
        this.executionContext = executionContext;
 
        Map<String, EntityManagerFactory> emfs = ReflectionUtils.getFieldValue(
            jpaApi, 
            "emfs"
        );
 
        this.hypersistenceOptimizer = new HypersistenceOptimizer(
            new JpaConfig(emfs.get("default"))
        );
    }
 
    //Code omitted for brevity
}

Why not get the EntityManagerFactory from withTransaction?

Getting the EntityManagerFactory via reflection is the only we can get access to the decorated SessionFactory, which allows Hypersistence Optimizer to intercept queries or the Persistence Context actions.

While this is the idiomatic way of getting the EntityManagerFactory when using Play Framework:

EntityManagerFactory emf = jpaApi.withTransaction(entityManager -> {
    return entityManager.getEntityManagerFactory();
});

Because the EntityManager reference provided to the withTransaction method is no longer associated with the decorated SessionFactory, this approach is not recommended.

So, use the ReflectionUtils class, that’s provided by Hypersistence Optimizer, to get access to the emfs field of the DefaultJPAApi object because that’s where the decorated SessionFactory is stored by the Play Framework.

The hypersistence-optimizer-play-example GitHub project demonstrates how you can use Hypersistence Optimizer in a Play Framework project.

JDK and Hibernate requirements

The compatibility matrix between Hibernate, JPA and Java versions looks as follows:

Hibernate JPA Java
6.4 3.1 Java 11 or newer
6.3 3.1 Java 11 or newer
6.2 3.1 Java 11 or newer
6.1 3.1 Java 11 or newer
6.0 3.0 Java 11 or newer
5.6 2.2 Java 8 or newer
5.5 2.2 Java 8 or newer
5.4 2.2 Java 8 or newer
5.3 2.2 Java 8 or above
5.2 2.1 Java 8 or newer
5.1 2.1 Java 8 or newer
5.0 2.1 Java 6 or newer
4.3 2.1 Java 6 or newer
4.2 2.0 Java 6 or newer
4.1 2.0 Java 6 or newer
3.6 2.0 Java 6 or newer
3.5 2.0 Java 6 or newer
3.3 1.0 Java 6 or newer

Therefore, you need to make sure that you are using the proper Java version based on what Hibernate is compiled with. Hypersistence Optimizer simply follows the Hibernate minimum Java requirement. So, if you’re using Hibernate 5.0, you can use Java 1.6 and Hypersistence Optimizer will work just fine.

If your application is running on a Java EE application server (e.g., JBoss 5) that instruments all classes found on your current Java 6 or 7 classpath, you might want to use the jre6 hypersistence-optimizer dependency version, as previously explained.

If you’re using an IBM JDK, you should also set the com.ibm.crypto.provider.DoRSATypeChecking JVM property to false as, by default, the IBM JDK does not allow you to decrypt the license key using the provided public key.

-Dcom.ibm.crypto.provider.DoRSATypeChecking=false

For more details, check out this StackOverflow thread.

Other than Hibernate, Hypersistence Optimizer does not require any other dependency. For logging, it can use either SLF4J, if you already configured it into your application or JBoss logging, which is required by Hibernate anyway.

Using an external Hypersistence Optimizer license file

Normally, you don’t need to specify any license file since Hypersistence Optimizer comes with an embedded license key. However, if you are using a managed environment (e.g., OSGI), which prevents loading the license file from the Hypersistence Optimizer jar, then you might want to set the license using an external URL:

new HypersistenceOptimizer(
    new JpaConfig(entityManagerFactory())
    .setLicenseFileUrl(new URL("file:///path/to/license/file"))
);

User Guide

And, that’s pretty much what you need in order to install Hypersistence Optimizer.

Now, you should proceed with the User Guide to see how you can configure and customize Hypersistence Optimizer.

Release Notes

You can check out the release notes using the following link.