Chapter 6. Events, Interceptors, and Envers

In this chapter, we will take a look at Hibernate events, interceptors, and envers. Additionally, to understand the internals of Hibernate as they relate to some of the concepts in this chapter, we will also cover the concept of a Java Service Provider Interface (SPI) and its use in Hibernate. Events and interceptors can be triggered when we load or store entities in the persistence context. In this chapter, you will see how you can use them to implement a functionality similar to DB triggers and other event-based functions. Furthermore, this chapter covers entity auditing (envers), which implements entity revision management to automatically store historical snapshots of entities and also provides auditing mechanism. This is useful for implementing an audit mechanism in your application and allows you to implement a rollback mechanism.

  • Services:
    • Service loader
    • Service registry
    • OSGi model
  • Events:
    • Event listener
    • Registering listeners
  • Interceptors:
    • Database trigger
    • Event or interceptor
  • Envers:
    • Configuration
    • Strategy
    • Fetching revisions

Services

The concept of services is not new in Java. It is a fundamental concept that has been around since JDK 1.3, which is known as the Java extension mechanism. The idea is to make your application more modular, extensible, and pluggable, where you, as the developer, may provide the default behavior and also implement the capability to extend your application beyond the defaults and let the behavior change at deploy time or, perhaps, even at runtime. If you are familiar with the Spring framework, the concept of services is very much like dependency injection and inversion of control.

As you may already know, a Service is a published contract, a set of operations with a well-defined interface. In Java, a service can be implemented using an interface or an abstract class. A service provider offers the concrete implementation of the service. As a Java developer, you use or implement services and providers every day, and you may not actively think about it. JDBC is a good example. The API is the service interface and the underlying database-specific driver is the concrete implementation.

We will not spend too much time discussing the Service Provider Interface or the OSGi model, as those topics are beyond the scope of this book. But, we will touch on these topics on the surface so that you understand the internals of Hibernate better.

Service loader

JDK 1.6 introduced the concept of a service loader, which makes it easy to provide a service implementation. Service providers are discovered simply by looking at the META-INF/services filesystem location in the class path.

As mentioned earlier, most JDBC drivers follow the service provider interface as defined by the Java specification. If you explode your database-specific driver JAR, chances are that you will see a META-INF/services directory that includes a file called java.sql.Driver, which points to the specific implementation of that interface.

Service registry

Another important concept, when discussing services, is the concept of a service registry. This is the mechanism that allows your application to discover the concrete implementation of a service.

As mentioned earlier, the service loader in Java looks for implementations in the META-INF/services directory. This is similar to package scans in Spring to resolve auto-wired beans or looking up an EJB instance via JNDI.

Creating a session factory is another good example of using the registry mechanism. Prior to Hibernate 4, you could create a session factory class from the Configuration class. But, the service registry builder has replaced this because containers such as Spring and EJB can manage the session factory by providing a session service registry. For example, in a simple application that doesn't run inside an application container, you may create a session factory as follows:

private static SessionFactory buildSessionFactory() {
    try {
     Configuration configuration = new Configuration().configure()
          .addAnnotatedClass(Person.class);
      
      StandardServiceRegistryBuilder builder = 
          new StandardServiceRegistryBuilder()
        .applySettings(configuration.getProperties());

      serviceRegistry = builder.build();
      return configuration.buildSessionFactory(serviceRegistry);
    }
    catch (Throwable ex) {
      // handle exception
        throw new ExceptionInInitializerError(ex);
    }
}

However, a container such as Spring can create and manage the session factory and wire sessions when needed. We will see more on this in Chapter 9, EJB and Spring Context.

The OSGi model

As mentioned in Chapter 1, Entity and Session, since version 4, Hibernate has been moving closer to the OSGi model. This model extends the idea of services one step further, in that, bundles can be installed, discovered, and removed or replaced at runtime. Furthermore, OSGi allows the tighter declaration of dependencies between services.

OSGi also implements a notification mechanism, where consumers are notified when a service becomes available or unavailable.

We can now safely discuss events and how they are implemented in Hibernate.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.133.123.126