13.5. Hibernate Services
13.5.1. About Hibernate Services
13.5.2. About Service Contracts
org.hibernate.service.Service
. Hibernate uses this internally for some basic type safety.
org.hibernate.service.spi.Startable
and org.hibernate.service.spi.Stoppable
interfaces to receive notifications of being started and stopped. Another optional service contract is org.hibernate.service.spi.Manageable
which marks the service as manageable in JMX provided the JMX integration is enabled.
13.5.3. Types of Service Dependencies
- @
org.hibernate.service.spi.InjectService
- Any method on the service implementation class accepting a single parameter and annotated with @
InjectService
is considered requesting injection of another service.By default the type of the method parameter is expected to be the service role to be injected. If the parameter type is different than the service role, theserviceRole
attribute of theInjectService
should be used to explicitly name the role.By default injected services are considered required, that is the start up will fail if a named dependent service is missing. If the service to be injected is optional, therequired
attribute of theInjectService
should be declared asfalse
(default istrue
). org.hibernate.service.spi.ServiceRegistryAwareService
- The second approach is a pull approach where the service implements the optional service interface
org.hibernate.service.spi.ServiceRegistryAwareService
which declares a singleinjectServices
method.During startup, Hibernate will inject theorg.hibernate.service.ServiceRegistry
itself into services which implement this interface. The service can then use theServiceRegistry
reference to locate any additional services it needs.
13.5.4. The ServiceRegistry
13.5.4.1. About the ServiceRegistry
org.hibernate.service.ServiceRegistry
interface. The main purpose of a service registry is to hold, manage and provide access to services.
org.hibernate.service.ServiceRegistryBuilder
to build a org.hibernate.service.ServiceRegistry
instance.
Example 13.21. Use ServiceRegistryBuilder to create a ServiceRegistry
ServiceRegistryBuilder registryBuilder = new ServiceRegistryBuilder( bootstrapServiceRegistry ); ServiceRegistry serviceRegistry = registryBuilder.buildServiceRegistry();
ServiceRegistryBuilder registryBuilder = new ServiceRegistryBuilder( bootstrapServiceRegistry );
ServiceRegistry serviceRegistry = registryBuilder.buildServiceRegistry();
13.5.5. Custom Services
13.5.5.1. About Custom Services
org.hibernate.service.ServiceRegistry
is built it is considered immutable; the services themselves might accept re-configuration, but immutability here means adding/replacing services. So another role provided by the org.hibernate.service.ServiceRegistryBuilder
is to allow tweaking of the services that will be contained in the org.hibernate.service.ServiceRegistry
generated from it.
org.hibernate.service.ServiceRegistryBuilder
about custom services.
- Implement a
org.hibernate.service.spi.BasicServiceInitiator
class to control on-demand construction of the service class and add it to theorg.hibernate.service.ServiceRegistryBuilder
via itsaddInitiator
method. - Just instantiate the service class and add it to the
org.hibernate.service.ServiceRegistryBuilder
via itsaddService
method.
Example 13.22. Use ServiceRegistryBuilder to Replace an Existing Service with a Custom Service
ServiceRegistryBuilder registryBuilder = new ServiceRegistryBuilder( bootstrapServiceRegistry ); registryBuilder.addService( JdbcServices.class, new FakeJdbcService() ); ServiceRegistry serviceRegistry = registryBuilder.buildServiceRegistry(); public class FakeJdbcService implements JdbcServices{ @Override public ConnectionProvider getConnectionProvider() { return null; } @Override public Dialect getDialect() { return null; } @Override public SqlStatementLogger getSqlStatementLogger() { return null; } @Override public SqlExceptionHelper getSqlExceptionHelper() { return null; } @Override public ExtractedDatabaseMetaData getExtractedMetaDataSupport() { return null; } @Override public LobCreator getLobCreator(LobCreationContext lobCreationContext) { return null; } @Override public ResultSetWrapper getResultSetWrapper() { return null; } }
ServiceRegistryBuilder registryBuilder = new ServiceRegistryBuilder( bootstrapServiceRegistry );
registryBuilder.addService( JdbcServices.class, new FakeJdbcService() );
ServiceRegistry serviceRegistry = registryBuilder.buildServiceRegistry();
public class FakeJdbcService implements JdbcServices{
@Override
public ConnectionProvider getConnectionProvider() {
return null;
}
@Override
public Dialect getDialect() {
return null;
}
@Override
public SqlStatementLogger getSqlStatementLogger() {
return null;
}
@Override
public SqlExceptionHelper getSqlExceptionHelper() {
return null;
}
@Override
public ExtractedDatabaseMetaData getExtractedMetaDataSupport() {
return null;
}
@Override
public LobCreator getLobCreator(LobCreationContext lobCreationContext) {
return null;
}
@Override
public ResultSetWrapper getResultSetWrapper() {
return null;
}
}
13.5.6. The Bootstrap Registry
13.5.6.1. About the Boot-strap Registry
ClassLoaderService
which is a perfect example. Even resolving configuration files needs access to class loading services (resource look ups). This is the root registry (no parent) in normal use.
org.hibernate.service.BootstrapServiceRegistryBuilder
class.
13.5.6.2. Using BootstrapServiceRegistryBuilder
Example 13.23. Using BootstrapServiceRegistryBuilder
BootstrapServiceRegistry bootstrapServiceRegistry = new BootstrapServiceRegistryBuilder() // pass in org.hibernate.integrator.spi.Integrator instances which are not // auto-discovered (for whatever reason) but which should be included .with( anExplicitIntegrator ) // pass in a class loader that Hibernate should use to load application classes .with( anExplicitClassLoaderForApplicationClasses ) // pass in a class loader that Hibernate should use to load resources .with( anExplicitClassLoaderForResources ) // see BootstrapServiceRegistryBuilder for rest of available methods ... // finally, build the bootstrap registry with all the above options .build();
BootstrapServiceRegistry bootstrapServiceRegistry = new BootstrapServiceRegistryBuilder()
// pass in org.hibernate.integrator.spi.Integrator instances which are not
// auto-discovered (for whatever reason) but which should be included
.with( anExplicitIntegrator )
// pass in a class loader that Hibernate should use to load application classes
.with( anExplicitClassLoaderForApplicationClasses )
// pass in a class loader that Hibernate should use to load resources
.with( anExplicitClassLoaderForResources )
// see BootstrapServiceRegistryBuilder for rest of available methods
...
// finally, build the bootstrap registry with all the above options
.build();
13.5.6.3. BootstrapRegistry Services
org.hibernate.service.classloading.spi.ClassLoaderService
- the ability to locate application classes
- the ability to locate integration classes
- the ability to locate resources (properties files, xml files, etc)
- the ability to load
java.util.ServiceLoader
Note
org.hibernate.integrator.spi.IntegratorService
java.util.ServiceLoader
capability provided by the org.hibernate.service.classloading.spi.ClassLoaderService
in order to discover implementations of the org.hibernate.integrator.spi.Integrator
contract.
/META-INF/services/org.hibernate.integrator.spi.Integrator
and make it available on the classpath.
java.util.ServiceLoader
mechanism. It lists, one per line, the fully qualified names of classes which implement the org.hibernate.integrator.spi.Integrator
interface.
13.5.7. The SessionFactory Registry
13.5.7.1. SessionFactory Registry
org.hibernate.SessionFactory
, the instances of services in this group explicitly belong to a single org.hibernate.SessionFactory
.
org.hibernate.SessionFactory
to be initiated. This special registry is org.hibernate.service.spi.SessionFactoryServiceRegistry
13.5.7.2. SessionFactory Services
org.hibernate.event.service.spi.EventListenerRegistry
- Description
- Service for managing event listeners.
- Initiator
org.hibernate.event.service.internal.EventListenerServiceInitiator
- Implementations
org.hibernate.event.service.internal.EventListenerRegistryImpl
13.5.8. Integrators
13.5.8.1. Integrators
org.hibernate.integrator.spi.Integrator
is intended to provide a simple means for allowing developers to hook into the process of building a functioning SessionFactory. The org.hibernate.integrator.spi.Integrator
interface defines 2 methods of interest: integrate
allows us to hook into the building process; disintegrate
allows us to hook into a SessionFactory shutting down.
Note
org.hibernate.integrator.spi.Integrator
, an overloaded form of integrate
accepting a org.hibernate.metamodel.source.MetadataImplementor
instead of org.hibernate.cfg.Configuration
. This form is intended for use with the new metamodel code scheduled for completion in 5.0.
13.5.8.2. Integrator use-cases
org.hibernate.integrator.spi.Integrator
right now are registering event listeners and providing services (see org.hibernate.integrator.spi.ServiceContributingIntegrator
). With 5.0 we plan on expanding that to allow altering the metamodel describing the mapping between object and relational models.
Example 13.24. Registering event listeners
public class MyIntegrator implements org.hibernate.integrator.spi.Integrator { public void integrate( Configuration configuration, SessionFactoryImplementor sessionFactory, SessionFactoryServiceRegistry serviceRegistry) { // As you might expect, an EventListenerRegistry is the thing with which event listeners are registered It is a // service so we look it up using the service registry final EventListenerRegistry eventListenerRegistry = serviceRegistry.getService( EventListenerRegistry.class ); // If you wish to have custom determination and handling of "duplicate" listeners, you would have to add an // implementation of the org.hibernate.event.service.spi.DuplicationStrategy contract like this eventListenerRegistry.addDuplicationStrategy( myDuplicationStrategy ); // EventListenerRegistry defines 3 ways to register listeners: // 1) This form overrides any existing registrations with eventListenerRegistry.setListeners( EventType.AUTO_FLUSH, myCompleteSetOfListeners ); // 2) This form adds the specified listener(s) to the beginning of the listener chain eventListenerRegistry.prependListeners( EventType.AUTO_FLUSH, myListenersToBeCalledFirst ); // 3) This form adds the specified listener(s) to the end of the listener chain eventListenerRegistry.appendListeners( EventType.AUTO_FLUSH, myListenersToBeCalledLast ); } }
public class MyIntegrator implements org.hibernate.integrator.spi.Integrator {
public void integrate(
Configuration configuration,
SessionFactoryImplementor sessionFactory,
SessionFactoryServiceRegistry serviceRegistry) {
// As you might expect, an EventListenerRegistry is the thing with which event listeners are registered It is a
// service so we look it up using the service registry
final EventListenerRegistry eventListenerRegistry = serviceRegistry.getService( EventListenerRegistry.class );
// If you wish to have custom determination and handling of "duplicate" listeners, you would have to add an
// implementation of the org.hibernate.event.service.spi.DuplicationStrategy contract like this
eventListenerRegistry.addDuplicationStrategy( myDuplicationStrategy );
// EventListenerRegistry defines 3 ways to register listeners:
// 1) This form overrides any existing registrations with
eventListenerRegistry.setListeners( EventType.AUTO_FLUSH, myCompleteSetOfListeners );
// 2) This form adds the specified listener(s) to the beginning of the listener chain
eventListenerRegistry.prependListeners( EventType.AUTO_FLUSH, myListenersToBeCalledFirst );
// 3) This form adds the specified listener(s) to the end of the listener chain
eventListenerRegistry.appendListeners( EventType.AUTO_FLUSH, myListenersToBeCalledLast );
}
}