1.4. Types of ServiceRegistries

Currently Hibernate utilizes three different ServiceRegistry implementations forming a hierarchy. Each type is a specialization for the purpose of type-safety, but they add no new functionality.

1.4.1. BootstrapServiceRegistry

The org.hibernate.boot.registry.BootstrapServiceRegistry holds three Service and is normally built by means of the org.hibernate.boot.registry.BootstrapServiceRegistryBuilder factory class. The builder gives type safe access to customizing these three Services.

This registry holds services that absolutely have to be available for most things in Hibernate to work.

In normal usage, the BootstrapServiceRegistry has no parent.

The services of the BootstrapServiceRegistry cannot be extended (added to) nor overridden (replaced).

ClassLoaderService

The Service role for this Service is org.hibernate.boot.registry.classloading.spi.ClassLoaderService. This Service defines Hibernate’s ability to interact with ClassLoaders. The manner in which Hibernate (or any library) should interact with ClassLoaders varies based on the runtime environment which is hosting the application. Application servers, OSGi containers, and other modular class loading systems impose very specific class-loading requirements. This Service provides Hibernate an abstraction from this environmental complexity. And just as important, it does so in a centralized, swappable manner.

The specific capabilities exposed on this Service include:

  • Locating Class references by name. This includes application classes as well as integration classes.

  • Locating resources (properties files, xml files, etc) as classpath resources

  • Interacting with java.util.ServiceLoader, Java’s own Service provider discovery mechanism

IntegratorService

The Service role for this Service is org.hibernate.integrator.spi.IntegratorService. Applications, third-party integrators and others all need to integrate with Hibernate. Historically this used to require something (usually the application) to coordinate registering the pieces of each integration needed on behalf of each integration. The org.hibernate.integrator.spi.Integrator contract formalized this “integration SPI”. The IntegratorService manages all known integrators.

The concept of “Integrator” is still being actively defined and developed. Expect changes in these SPIs.

There are two ways an integrator becomes known.

  • The integrator may be manually registered by calling BootstrapServiceRegistryBuilder#with(Integrator)

  • The integrator may be discovered, leveraging the standard Java ServiceLoader capability provided by the ClassLoaderService. Integrators would simply define a file named /META-INF/services/org.hibernate.integrator.spi.Integrator and make it available on the classpath. ServiceLoader covers the format of this file in detail, but essentially it lists classes by fully-qualified name that implement Integrator one per line.

StrategySelector

The Service role for this Service is org.hibernate.boot.registry.selector.spi.StrategySelector. Think of this as the short naming service. Historically to configure Hibernate users would often need to give fully-qualified name references to internal Hibernate classes. Of course, this has caused lots of problems as we refactor internal code and move these classes around into different package structures. Enter the concept of short-naming, using a well defined and well known short name for the strategy/implementation class.

The short name mappings in this Service can be managed, even by applications and integrators which can be very powerful. For more information on this aspect, see:

  • BootstrapServiceRegistryBuilder#applyStrategySelector

  • BootstrapServiceRegistryBuilder#applyStrategySelectors

  • org.hibernate.boot.registry.selector.StrategyRegistrationProvider via ServiceLoader discovery

  • StrategySelector#registerStrategyImplementor / StrategySelector#unRegisterStrategyImplementor

1.4.2. StandardServiceRegistry

The org.hibernate.boot.registry.StandardServiceRegistry defines the main Hibernate ServiceRegistry, building on the BootstrapServiceRegistry which is its parent. This registry is generally built using the org.hibernate.boot.registry.StandardServiceRegistryBuilder class. By default, it holds most of the Services used by Hibernate. For the full list of Services typically held in the StandardServiceRegistry, see the source code of org.hibernate.service.StandardServiceInitiators.

In normal usage, the parent of the StandardServiceRegistry is the BootstrapServiceRegistry.

The services of the StandardServiceRegistry can be extended (added to) and overridden (replaced).

ConnectionProvider/MultiTenantConnectionProvider

The Service providing Hibernate with Connections as needed. Comes in two distinct (and mutually exclusive) roles:

org.hibernate.engine.jdbc.connections.spi.ConnectionProvider

provides Connections in normal environments

org.hibernate.engine.jdbc.connections.spi.MultiTenantConnectionProvider

provides (tenant-specific) Connections in multi-tenant environments

JdbcServices

org.hibernate.engine.jdbc.spi.JdbcServices is an aggregator Service (a Service that aggregates other Services) exposing unified functionality around JDBC accessibility.

TransactionCoordinatorBuilder

org.hibernate.resource.transaction.spi.TransactionCoordinatorBuilder is used by Hibernate to integrate with and underlying transaction system. It is responsible for building org.hibernate.resource.transaction.spi.TransactionCoordinator instances for use by each Hibernate Session.

JtaPlatform

When using a JTA-based TransactionCoordinatorBuilder, the org.hibernate.engine.transaction.jta.platform.spi.JtaPlatform Service provides Hibernate access to the JTA TransactionManager and UserTransaction, as well handling Synchronization registration.

JndiService

The org.hibernate.engine.jndi.spi.JndiService Service is used by Hibernate to interact with JNDI contexts. Hibernate’s default JndiService assumes just a single InitialContext.

RegionFactory

The org.hibernate.cache.spi.RegionFactory Service defines the integration with third party cache implementors as second-level caching providers.

SessionFactoryServiceRegistryFactory

org.hibernate.service.spi.SessionFactoryServiceRegistryFactory is a Service that acts as a factory for building the third type of ServiceRegistry (the SessionFactoryServiceRegistry) which we will discuss next. I opted for the factory as service approach because in the current design there is really not a good exposed hook-in spot for when the SessionFactoryServiceRegistry needs to be built.

1.4.3. SessionFactoryServiceRegistry

org.hibernate.service.spi.SessionFactoryServiceRegistry is the third standard Hibernate ServiceRegistry. SessionFactoryServiceRegistry is designed to hold Services which need access to the SessionFactory.

Typically its parent registry is the StandardServiceRegistry.

Integrators, as it stands in 4.x, operate on the SessionFactoryServiceRegistry.

Currently SessionFactoryServiceRegistry holds just four Services.

EventListenerRegistry

org.hibernate.event.service.spi.EventListenerRegistry is the main Service managed in the SessionFactoryServiceRegistry. The is the Service that manages all of Hibernate’s event listeners. A major use-case for Integrators is to alter the listener registry.

If doing custom listener registration, it is important to understand the org.hibernate.event.service.spi.DuplicationStrategy and its effect on registration. The basic idea is to tell Hibernate:

  • what makes a listener a duplicate

  • how to handle duplicate registrations (error, first wins, last wins)

StatisticsImplementor

org.hibernate.stat.spi.StatisticsImplementor is the SPI portion of the Statistics API; the collector portion, if you will.

NativeQueryInterpreter

org.hibernate.engine.query.spi.NativeQueryInterpreter is the Service Hibernate uses for interpreting native queries. Exists as a Service mainly so that integrations such as OGM can override it.

CacheImplementor

org.hibernate.engine.spi.CacheImplementor provides a way to customize the way Hibernate interacts with the second-level caching implementation.