AdBlock Detected

It looks like you're using an ad-blocker!

Our team work realy hard to produce quality content on this website and we noticed you have ad-blocking enabled. Advertisements and advertising enable us to continue working and provide high-quality content.

Hibernate Interceptors

In this post we will see a guide to Hibernate interceptors, so we can apply and use them based on certain events that may occur in our application.

What is Hibernate?

Hibernate is an Object Relational Mapping (ORM) for Java that allows us to map our objects to a relational database. It provides a framework for interacting with and creating relationships and queries against the database.

What are Hibernate interceptors?

Hibernate interceptors are an interface that allows us to react to certain types of events that occur in Hibernate.

Once registered, interceptors allow communication between our application and the Hibernate session.

To create an interceptor in Hibernate, we can use two different approaches:

  • Use the Hibernate Interceptor interface.
  • Extend the EmptyInterceptor class.

For example, we could say that Hibernate interceptors work similarly to JPA’s @Prepersist and @PreUpdate.

Once the interceptor has been created, it needs to be registered, which can be done using Session-scoped or SessionFactory-scoped.

Creating an interceptor in Hibernate by extending EmptyInterceptor

By extending the EmptyInterceptor class, we can create an interceptor in Hibernate in a simple and fast way. It is only necessary to override the methods we need from the EmptyInterceptor class:

public class HibernateCustomInterceptor extends EmptyInterceptor {

@Override
public boolean onSave(Object entity, Serializable id, 
  Object[] state, String[] propertyNames, Type[] types) {
    
    if (entity instanceof Customer) {
        logger.info(((Customer) entity).toString());
    }
    return super.onSave(entity, id, state, propertyNames, types);
}
}

Other methods we can override include onLoad, onDelete, or onFlushDirty.

Interceptor in Hibernate implementing the Interceptor class

This approach allows us to implement 15 methods of the Hibernate Interceptor class. If we do not need any special or additional implementation, it is not necessary.

public class HibernateCustomInterceptor implements Interceptor, Serializable {

    @Override
    public boolean onLoad(Object entity, Serializable id, 
      Object[] state, String[] propertyNames, Type[] types) 
      throws CallbackException {
        
        return false;
    }

   

    @Override
    public String onPrepareStatement(String sql) {
        // do something  
        return sql;
    }

......

}

Registering a Hibernate interceptor with Session-scoped

Once we have created our interceptor, we will register it using Session-scoped. An interceptor registered as Session-scoped is linked to a specific Hibernate session:

public static Session sessionWithInterceptor(Interceptor interceptor) 
  throws IOException {
    return getSessionFactory().withOptions()
      .interceptor(interceptor).openSession();
}

public static SessionFactory getSessionFactory(String propertyFileName) throws IOException {
        if (sessionFactory == null) {
            ServiceRegistry serviceRegistry = configureServiceRegistry();
            sessionFactory = getSessionFactoryBuilder(serviceRegistry).build();
        }
        return sessionFactory;
}

Registering a Hibernate interceptor with SessionFactory-scoped

With the approach of registering a Hibernate interceptor with SessionFatory-scoped, it will be registered before building the SessionFactory.

To register the interceptor, we use the applyInterceptor method of the SessionFactoryBuilder.

ServiceRegistry serviceInterceptorRegistry = configureServiceRegistry();
SessionFactory sessionFactory = getSessionFactoryBuilder(serviceInterceptorRegistry)
  .applyInterceptor(new CustomInterceptor())
  .build();



    private static ServiceRegistry configureServiceRegistry() throws IOException {
        Properties properties = getProperties();
        return new StandardServiceRegistryBuilder().applySettings(properties)
            .build();
    }

    private static SessionFactoryBuilder getSessionFactoryBuilder(ServiceRegistry serviceRegistry) {
        
        MetadataSources metadataSources = new MetadataSources(serviceRegistry);
        metadataSources.addPackage("com.refactorizando.example.hibernate.interceptors");
        metadataSources.addAnnotatedClass(User.class);

        Metadata metadata = metadataSources.buildMetadata();
        return metadata.getSessionFactoryBuilder();

    }

When we register an interceptor using this approach, it will be applied to all Hibernate sessions.

To avoid concurrent issues and make the interceptor thread-safe, we need to specify the session context in our configuration file:

hibernate:
  current_session_context_class: org.hibernate.context.internal.ThreadLocalSessionContext

Conclusion

In this small guide to Hibernate interceptors, we have seen the different approaches for registering and implementing an interceptor in Hibernate. The use of interceptors in Hibernate allows us to react to certain events, such as when calling save(), and thus interact with the Hibernate Session by adding or modifying data before saving.

If you need more information, you can leave us a comment or send an email to refactorizando.web@gmail.com You can also contact us through our social media channels on Facebook or twitter and we will be happy to assist you!!

Leave a Reply

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