HHH-10006 - Document configuration of JndiService;
HHH-10007 - Audit Services chapter in Integrations Guide
This commit is contained in:
parent
2036280fa0
commit
8f4c2d5182
|
@ -6,7 +6,8 @@
|
||||||
~ License: GNU Lesser General Public License (LGPL), version 2.1 or later.
|
~ License: GNU Lesser General Public License (LGPL), version 2.1 or later.
|
||||||
~ See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
~ See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
||||||
-->
|
-->
|
||||||
<chapter xmlns="http://docbook.org/ns/docbook"
|
<chapter xml:id="services"
|
||||||
|
xmlns="http://docbook.org/ns/docbook"
|
||||||
xmlns:xi="http://www.w3.org/2001/XInclude">
|
xmlns:xi="http://www.w3.org/2001/XInclude">
|
||||||
|
|
||||||
<title>Services and Registries</title>
|
<title>Services and Registries</title>
|
||||||
|
@ -20,7 +21,7 @@
|
||||||
applications can leverage and customize Services and Registries.
|
applications can leverage and customize Services and Registries.
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
<section>
|
<section xml:id="services-service">
|
||||||
<title>What is a Service?</title>
|
<title>What is a Service?</title>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
|
@ -58,7 +59,7 @@
|
||||||
practice. What's interesting is the ServiceRegistry and the pluggable swapping of the different implementors.
|
practice. What's interesting is the ServiceRegistry and the pluggable swapping of the different implementors.
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
<section>
|
<section xml:id="services-contracts">
|
||||||
<title>Service contracts</title>
|
<title>Service contracts</title>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
|
@ -190,7 +191,7 @@
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
|
|
||||||
<section>
|
<section xml:id="services-binding">
|
||||||
<title>ServiceBinding</title>
|
<title>ServiceBinding</title>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
|
@ -203,8 +204,16 @@
|
||||||
<para>
|
<para>
|
||||||
There are 2 ways a Service becomes associated (bound) to a ServiceRegistry.
|
There are 2 ways a Service becomes associated (bound) to a ServiceRegistry.
|
||||||
<itemizedlist>
|
<itemizedlist>
|
||||||
<listitem>the Service can be directly instantiated and then handed to the ServiceRegistry</listitem>
|
<listitem>
|
||||||
<listitem>a ServiceInitiator can be given to the ServiceRegistry (which the ServiceRegistry will use if and when the Service is needed)</listitem>
|
<para>
|
||||||
|
the Service can be directly instantiated and then handed to the ServiceRegistry
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
a ServiceInitiator can be given to the ServiceRegistry (which the ServiceRegistry will use if and when the Service is needed)
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
</itemizedlist>
|
</itemizedlist>
|
||||||
ServiceRegistry implementations register bindings through calls to the overloaded
|
ServiceRegistry implementations register bindings through calls to the overloaded
|
||||||
<methodname>org.hibernate.service.internal.AbstractServiceRegistryImpl#createServiceBinding</methodname>
|
<methodname>org.hibernate.service.internal.AbstractServiceRegistryImpl#createServiceBinding</methodname>
|
||||||
|
@ -217,7 +226,7 @@
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
|
|
||||||
<section>
|
<section xml:id="services-registry-types">
|
||||||
<title>Types of ServiceRegistries</title>
|
<title>Types of ServiceRegistries</title>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
|
@ -225,7 +234,7 @@
|
||||||
type is a specialization for the purpose of type-safety, but they add no new functionality.
|
type is a specialization for the purpose of type-safety, but they add no new functionality.
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
<section>
|
<section xml:id="services-registry-boot">
|
||||||
<title>BootstrapServiceRegistry</title>
|
<title>BootstrapServiceRegistry</title>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
|
@ -268,9 +277,22 @@
|
||||||
<para>
|
<para>
|
||||||
The specific capabilities exposed on this service include:
|
The specific capabilities exposed on this service include:
|
||||||
<itemizedlist>
|
<itemizedlist>
|
||||||
<listitem>Locating Class references by name. This includes application classes as well as "integration" classes.</listitem>
|
<listitem>
|
||||||
<listitem>Locating resources (properties files, xml files, etc) as "classpath resources"</listitem>
|
<para>
|
||||||
<listitem>Interacting with <classname>java.util.ServiceLoader</classname>, Java's own service provider discovery mechanism</listitem>
|
Locating Class references by name. This includes application classes as well as "integration" classes.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
Locating resources (properties files, xml files, etc) as "classpath resources"
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
Interacting with <classname>java.util.ServiceLoader</classname>, Java's own service
|
||||||
|
provider discovery mechanism
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
</itemizedlist>
|
</itemizedlist>
|
||||||
</para>
|
</para>
|
||||||
</section>
|
</section>
|
||||||
|
@ -339,15 +361,27 @@
|
||||||
The short name mappings in this service can be managed, even by applications and integrators
|
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:
|
which can be very powerful. For more information on this aspect, see:
|
||||||
<itemizedlist>
|
<itemizedlist>
|
||||||
<listitem><methodname>BootstrapServiceRegistryBuilder#applyStrategySelector</methodname></listitem>
|
|
||||||
<listitem><methodname>BootstrapServiceRegistryBuilder#applyStrategySelectors</methodname></listitem>
|
|
||||||
<listitem>
|
<listitem>
|
||||||
<interfacename>org.hibernate.boot.registry.selector.StrategyRegistrationProvider</interfacename>
|
<para>
|
||||||
via ServiceLoader discovery
|
<methodname>BootstrapServiceRegistryBuilder#applyStrategySelector</methodname>
|
||||||
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
<listitem>
|
<listitem>
|
||||||
|
<para>
|
||||||
|
<methodname>BootstrapServiceRegistryBuilder#applyStrategySelectors</methodname>
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
<interfacename>org.hibernate.boot.registry.selector.StrategyRegistrationProvider</interfacename>
|
||||||
|
via ServiceLoader discovery
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
<methodname>StrategySelector#registerStrategyImplementor`</methodname> /
|
<methodname>StrategySelector#registerStrategyImplementor`</methodname> /
|
||||||
<methodname>StrategySelector#unRegisterStrategyImplementor</methodname>
|
<methodname>StrategySelector#unRegisterStrategyImplementor</methodname>
|
||||||
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
</itemizedlist>
|
</itemizedlist>
|
||||||
</para>
|
</para>
|
||||||
|
@ -355,7 +389,7 @@
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
|
|
||||||
<section>
|
<section xml:id="services-registry-standard">
|
||||||
<title>StandardServiceRegistry</title>
|
<title>StandardServiceRegistry</title>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
|
@ -383,12 +417,16 @@
|
||||||
exclusive) roles:
|
exclusive) roles:
|
||||||
<itemizedlist>
|
<itemizedlist>
|
||||||
<listitem>
|
<listitem>
|
||||||
|
<para>
|
||||||
<interfacename>org.hibernate.engine.jdbc.connections.spi.ConnectionProvider</interfacename> -
|
<interfacename>org.hibernate.engine.jdbc.connections.spi.ConnectionProvider</interfacename> -
|
||||||
provides Connections in normal environments
|
provides Connections in normal environments
|
||||||
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
<listitem>
|
<listitem>
|
||||||
|
<para>
|
||||||
<interfacename>org.hibernate.engine.jdbc.connections.spi.MultiTenantConnectionProvider</interfacename> -
|
<interfacename>org.hibernate.engine.jdbc.connections.spi.MultiTenantConnectionProvider</interfacename> -
|
||||||
provides (tenant-specific) Connections in multi-tenant environments
|
provides (tenant-specific) Connections in multi-tenant environments
|
||||||
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
</itemizedlist>
|
</itemizedlist>
|
||||||
</para>
|
</para>
|
||||||
|
@ -453,7 +491,7 @@
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
|
|
||||||
<section>
|
<section xml:id="services-registry-sf">
|
||||||
<title>SessionFactoryServiceRegistry</title>
|
<title>SessionFactoryServiceRegistry</title>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
|
@ -488,8 +526,8 @@
|
||||||
<classname>org.hibernate.event.service.spi.DuplicationStrategy</classname> and its effect on
|
<classname>org.hibernate.event.service.spi.DuplicationStrategy</classname> and its effect on
|
||||||
registration. The basic idea is to tell Hibernate:
|
registration. The basic idea is to tell Hibernate:
|
||||||
<itemizedlist>
|
<itemizedlist>
|
||||||
<listitem>what makes a listener a duplicate</listitem>
|
<listitem><para>what makes a listener a duplicate</para></listitem>
|
||||||
<listitem>how to handle duplicate registrations (error, first wins, last wins)</listitem>
|
<listitem><para>how to handle duplicate registrations (error, first wins, last wins)</para></listitem>
|
||||||
</itemizedlist>
|
</itemizedlist>
|
||||||
</para>
|
</para>
|
||||||
</section>
|
</section>
|
||||||
|
@ -520,4 +558,126 @@
|
||||||
</section>
|
</section>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
|
<section xml:id="services-custom">
|
||||||
|
<title>Custom Services</title>
|
||||||
|
<para>
|
||||||
|
So far we have focused on the Hibernate provided services. But applications and integrations
|
||||||
|
can provide their own services as well, either
|
||||||
|
<itemizedlist>
|
||||||
|
<listitem>
|
||||||
|
<para>providing a new implementation of a standard service (overriding)</para>
|
||||||
|
</listitem>
|
||||||
|
<listitem>
|
||||||
|
<para>providing a whole new service role (extending)</para>
|
||||||
|
</listitem>
|
||||||
|
</itemizedlist>
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<section xml:id="services-overriding">
|
||||||
|
<title>Custom Service Implementations (overriding)</title>
|
||||||
|
<para>
|
||||||
|
We discussed swappability of service implementations above. Lets look at an example in practice.
|
||||||
|
For the sake of illustration, lets say that we have developed a new ConnectionProvider integrating
|
||||||
|
with the wonderful new latest-and-greatest connection pooling library. Let's look at the steps
|
||||||
|
necessary to make that happen.
|
||||||
|
</para>
|
||||||
|
<para>
|
||||||
|
The first step is to develop the actual integration by implementing the ConnectionProvider contract.
|
||||||
|
</para>
|
||||||
|
<example>
|
||||||
|
<title>Custom ConnectionProvider implementation</title>
|
||||||
|
<programlisting role="JAVA"><xi:include href="extras/override/LatestAndGreatestConnectionProviderImpl.java" parse="text" /></programlisting>
|
||||||
|
</example>
|
||||||
|
<para>
|
||||||
|
At this point we have a decision about how to integrate this new ConnectionProvider into Hibernate.
|
||||||
|
As you might guess, there are multiple ways.
|
||||||
|
</para>
|
||||||
|
<para>
|
||||||
|
As a first option, we might just require that the code bootstrapping the StandardServiceRegistry do
|
||||||
|
the integration.
|
||||||
|
</para>
|
||||||
|
<example>
|
||||||
|
<title>Overriding service implementation via StandardServiceRegistryBuilder</title>
|
||||||
|
<programlisting role="JAVA"><xi:include href="extras/override/ex1-direct.java" parse="text" /></programlisting>
|
||||||
|
</example>
|
||||||
|
<para>
|
||||||
|
A second option, if our LatestAndGreatestConnectionProviderImpl should always be used, would be to
|
||||||
|
provide a <interfacename>org.hibernate.service.spi.ServiceContributor</interfacename> implementation
|
||||||
|
as well to handle the integration on the users behalf.
|
||||||
|
</para>
|
||||||
|
<example>
|
||||||
|
<title>LatestAndGreatestConnectionProviderImplContributor</title>
|
||||||
|
<programlisting role="JAVA"><xi:include href="extras/override/ex2-contributor.java" parse="text" /></programlisting>
|
||||||
|
</example>
|
||||||
|
<para>
|
||||||
|
We still need to be able to tell Hibernate to perform this integration for us. To do that we leverage
|
||||||
|
Java's ServiceLoader. When building the StandardServiceRegistry, Hibernate will look for JDK
|
||||||
|
service providers of type <interfacename>org.hibernate.service.spi.ServiceContributor</interfacename>
|
||||||
|
and automatically integrate them. We discussed this behavior above. Here we'd define a classpath
|
||||||
|
resource named <filename>META-INF/services/org.hibernate.service.spi.ServiceContributor</filename>.
|
||||||
|
This file will have just a single line naming our impl.
|
||||||
|
</para>
|
||||||
|
<example>
|
||||||
|
<title>META-INF/services/org.hibernate.service.spi.ServiceContributor</title>
|
||||||
|
<programlisting><xi:include href="extras/override/ex2-meta-inf" parse="text" /></programlisting>
|
||||||
|
</example>
|
||||||
|
<para>
|
||||||
|
A third option, if we simply want to make our LatestAndGreatestConnectionProviderImpl available
|
||||||
|
as a configuration choice, we would again use a ServiceContributor but in a slightly
|
||||||
|
different way.
|
||||||
|
</para>
|
||||||
|
<example>
|
||||||
|
<title>LatestAndGreatestConnectionProviderImplContributor</title>
|
||||||
|
<programlisting role="JAVA"><xi:include href="extras/override/ex3-contributor.java" parse="text" /></programlisting>
|
||||||
|
</example>
|
||||||
|
<para>
|
||||||
|
That all allows the appication to pick our LatestAndGreatestConnectionProviderImpl by a short-name.
|
||||||
|
</para>
|
||||||
|
<example>
|
||||||
|
<title>Custom service short-name</title>
|
||||||
|
<programlisting role="JAVA"><xi:include href="extras/override/ex3-app.java" parse="text" /></programlisting>
|
||||||
|
</example>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section xml:id="services-extending">
|
||||||
|
<title>Custom Service Roles (extending)</title>
|
||||||
|
<para>
|
||||||
|
We can also have the ServiceRegistry host custom services (completely new Service roles). As an example,
|
||||||
|
let's say our application publishes Hibernate events to a JMS Topic and that we want to leverage the
|
||||||
|
Hibernate ServiceRegistry to host a Service representing our publishing of events. So we will expand the
|
||||||
|
ServiceRegistry to host this completely new Service role for us and manage its lifecycle.
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<example>
|
||||||
|
<title>The EventPublishingService service role</title>
|
||||||
|
<programlisting role="JAVA"><xi:include href="extras/extend/EventPublishingService.java" parse="text" /></programlisting>
|
||||||
|
</example>
|
||||||
|
|
||||||
|
<example>
|
||||||
|
<title>The EventPublishingService implementation</title>
|
||||||
|
<programlisting role="JAVA"><xi:include href="extras/extend/EventPublishingServiceImpl.java" parse="text" /></programlisting>
|
||||||
|
</example>
|
||||||
|
|
||||||
|
<example>
|
||||||
|
<title>An alternative EventPublishingService implementation</title>
|
||||||
|
<programlisting role="JAVA"><xi:include href="extras/extend/EventPublishingServiceImpl.java" parse="text" /></programlisting>
|
||||||
|
</example>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
Because we have alternative implementations, it is a good idea to develop an initiator as well
|
||||||
|
that can choose between them at runtime.
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<example>
|
||||||
|
<title>The EventPublishingServiceInitiator</title>
|
||||||
|
<programlisting role="JAVA"><xi:include href="extras/extend/EventPublishingServiceInitiator.java" parse="text" /></programlisting>
|
||||||
|
</example>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
We could have the application register the EventPublishingServiceInitiator with the
|
||||||
|
StandardServiceRegistryBuilder, but it is much nicer to write a ServiceContributor to handle this
|
||||||
|
for the application.
|
||||||
|
</para>
|
||||||
|
</section>
|
||||||
|
</section>
|
||||||
</chapter>
|
</chapter>
|
|
@ -0,0 +1,11 @@
|
||||||
|
public class DisabledEventPublishingServiceImpl implements EventPublishingService {
|
||||||
|
public static DisabledEventPublishingServiceImpl INSTANCE = new DisabledEventPublishingServiceImpl();
|
||||||
|
|
||||||
|
private DisabledEventPublishingServiceImpl() {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void publish(Event theEvent) {
|
||||||
|
// nothing to do...
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,3 @@
|
||||||
|
public interface EventPublishingService extends Service {
|
||||||
|
public void publish(Event theEvent);
|
||||||
|
}
|
|
@ -0,0 +1,12 @@
|
||||||
|
public class EventPublishingServiceContributor
|
||||||
|
implements ServiceContributor {
|
||||||
|
@Override
|
||||||
|
public void contribute(StandardServiceRegistryBuilder builder) {
|
||||||
|
builder.addInitiator( EventPublishingServiceInitiator.INSTANCE );
|
||||||
|
|
||||||
|
// if we wanted to allow other strategies (e.g. a JMS
|
||||||
|
// Queue publisher) we might also register short names
|
||||||
|
// here with the StrategySelector. The initiator would
|
||||||
|
// then need to accept the strategy as a config setting
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,50 @@
|
||||||
|
public class EventPublishingServiceImpl
|
||||||
|
implements EventPublishingService,
|
||||||
|
Configurable,
|
||||||
|
Startable,
|
||||||
|
Stoppable,
|
||||||
|
ServiceRegistryAwareService {
|
||||||
|
|
||||||
|
private ServiceRegistryImplementor serviceRegistry;
|
||||||
|
private String jmsConnectionFactoryName;
|
||||||
|
private String destinationName;
|
||||||
|
|
||||||
|
private Connection jmsConnection;
|
||||||
|
private Session jmsSession;
|
||||||
|
private MessageProducer publisher;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void injectServices(ServiceRegistryImplementor serviceRegistry) {
|
||||||
|
this.serviceRegistry = serviceRegistry;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void configure(Map configurationValues) {
|
||||||
|
this.jmsConnectionFactoryName = configurationValues.get( JMS_CONNECTION_FACTORY_NAME_SETTING );
|
||||||
|
this.destinationName = configurationValues.get( JMS_DESTINATION_NAME_SETTING );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void start() {
|
||||||
|
final JndiService jndiService = serviceRegistry.getService( JndiService.class );
|
||||||
|
final ConnectionFactory jmsConnectionFactory = jndiService.locate( jmsConnectionFactoryName );
|
||||||
|
|
||||||
|
this.jmsConnection = jmsConnectionFactory.createConnection();
|
||||||
|
this.jmsSession = jmsConnection.createSession( true, Session.AUTO_ACKNOWLEDGE );
|
||||||
|
|
||||||
|
final Destination destination = jndiService.locate( destinationName );
|
||||||
|
|
||||||
|
this.publisher = jmsSession.createProducer( destination );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void publish(Event theEvent) {
|
||||||
|
publisher.send( theEvent );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void stop() {
|
||||||
|
publisher.close();
|
||||||
|
jmsSession.close();
|
||||||
|
jmsConnection.close();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,22 @@
|
||||||
|
public class EventPublishingServiceInitiator implements StandardServiceInitiator<EventPublishingService> {
|
||||||
|
public static EventPublishingServiceInitiator INSTANCE = new EventPublishingServiceInitiator();
|
||||||
|
public static final String ENABLE_PUBLISHING_SETTING = "com.acme.EventPublishingService.enabled";
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Class<R> getServiceInitiated() {
|
||||||
|
return EventPublishingService.class;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public R initiateService(Map configurationValues, ServiceRegistryImplementor registry) {
|
||||||
|
final boolean enabled = extractBoolean( configurationValues, ENABLE_PUBLISHING_SETTING );
|
||||||
|
if ( enabled ) {
|
||||||
|
return new EventPublishingServiceImpl();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return DisabledEventPublishingServiceImpl.INSTANCE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
...
|
||||||
|
}
|
|
@ -0,0 +1,55 @@
|
||||||
|
import java.lang.Override;
|
||||||
|
|
||||||
|
public class LatestAndGreatestConnectionProviderImpl
|
||||||
|
implements ConnectionProvider, Startable, Stoppable, Configurable {
|
||||||
|
|
||||||
|
private LatestAndGreatestPoolBuilder lagPoolBuilder;
|
||||||
|
private LatestAndGreatestPool lagPool;
|
||||||
|
private boolean available = false;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void configure(Map configurationValues) {
|
||||||
|
// extract our config from the settings map
|
||||||
|
lagPoolBuilder = buildBuilder( configurationValues );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void start() {
|
||||||
|
// start the underlying pool
|
||||||
|
lagPool = lagPoolBuilder.buildPool();
|
||||||
|
|
||||||
|
available = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void stop() {
|
||||||
|
available = true;
|
||||||
|
|
||||||
|
// stop the underlying pool
|
||||||
|
lagPool.shutdown();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Connection getConnection() throws SQLException {
|
||||||
|
if ( !available ) {
|
||||||
|
throwException( "LatestAndGreatest ConnectionProvider not available for use" )
|
||||||
|
}
|
||||||
|
|
||||||
|
return lagPool.borrowConnection();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void closeConnection(Connection conn) throws SQLException {
|
||||||
|
if ( !available ) {
|
||||||
|
warn( "LatestAndGreatest ConnectionProvider not available for use" )
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( conn == null ) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
lagPool.releaseConnection( conn );
|
||||||
|
}
|
||||||
|
|
||||||
|
...
|
||||||
|
}
|
|
@ -0,0 +1,7 @@
|
||||||
|
StandardServiceRegistryBuilder builder = ...;
|
||||||
|
...
|
||||||
|
builder.addService(
|
||||||
|
ConnectionProvider.class,
|
||||||
|
new LatestAndGreatestConnectionProviderImpl()
|
||||||
|
);
|
||||||
|
...
|
|
@ -0,0 +1,10 @@
|
||||||
|
public class LatestAndGreatestConnectionProviderImplContributor1
|
||||||
|
implements ServiceContributor {
|
||||||
|
@Override
|
||||||
|
public void contribute(StandardServiceRegistryBuilder serviceRegistryBuilder) {
|
||||||
|
serviceRegistryBuilder.addService(
|
||||||
|
ConnectionProvider.class,
|
||||||
|
new LatestAndGreatestConnectionProviderImpl()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1 @@
|
||||||
|
fully.qualified.package.LatestAndGreatestConnectionProviderImplContributor1
|
|
@ -0,0 +1,4 @@
|
||||||
|
StandardServiceRegistryBuilder builder = ...;
|
||||||
|
...
|
||||||
|
builder.applySetting( "hibernate.connection.provider_class", "lag" );
|
||||||
|
...
|
|
@ -0,0 +1,14 @@
|
||||||
|
public class LatestAndGreatestConnectionProviderImplContributor1
|
||||||
|
implements ServiceContributor {
|
||||||
|
@Override
|
||||||
|
public void contribute(StandardServiceRegistryBuilder serviceRegistryBuilder) {
|
||||||
|
// here we will register a short-name for our service strategy
|
||||||
|
StrategySelector selector = serviceRegistryBuilder.getBootstrapServiceRegistry().
|
||||||
|
.getService( StrategySelector.class );
|
||||||
|
selector.registerStrategyImplementor(
|
||||||
|
ConnectionProvider.class,
|
||||||
|
"lag"
|
||||||
|
LatestAndGreatestConnectionProviderImpl.class
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1 @@
|
||||||
|
fully.qualified.package.LatestAndGreatestConnectionProviderImplContributor2
|
|
@ -0,0 +1,63 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!--
|
||||||
|
~ Hibernate, Relational Persistence for Idiomatic Java
|
||||||
|
~
|
||||||
|
~ License: GNU Lesser General Public License (LGPL), version 2.1 or later.
|
||||||
|
~ See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
||||||
|
-->
|
||||||
|
<chapter xml:id="JNDI.xml"
|
||||||
|
xml:lang="en"
|
||||||
|
xmlns="http://docbook.org/ns/docbook">
|
||||||
|
<title>JNDI</title>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
Hibernate does optionally interact with JNDI on the applications behalf. Generally
|
||||||
|
it does this when the application:
|
||||||
|
<itemizedlist>
|
||||||
|
<listitem>
|
||||||
|
<para>has asked the SessionFactory be bound to JNDI</para>
|
||||||
|
</listitem>
|
||||||
|
<listitem>
|
||||||
|
<para>has specified a DataSource to use by JNDI name</para>
|
||||||
|
</listitem>
|
||||||
|
<listitem>
|
||||||
|
<para>is using JTA transactions and the JtaPlatform needs to do JNDI lookups for TM, UT, etc</para>
|
||||||
|
</listitem>
|
||||||
|
</itemizedlist>
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
All of these JNDI calls route through a single service whose role is
|
||||||
|
<interfacename>org.hibernate.engine.jndi.spi.JndiService</interfacename>. The standard JndiService
|
||||||
|
accepts a number of configuration settings
|
||||||
|
<itemizedlist>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
<literal>hibernate.jndi.class</literal> - names the
|
||||||
|
<interfacename>javax.naming.InitialContext</interfacename> implementation class to use. See
|
||||||
|
<constant>javax.naming.Context#INITIAL_CONTEXT_FACTORY</constant>
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
<literal>hibernate.jndi.url</literal> - names the JNDI InitialContext connection url. See
|
||||||
|
<constant>javax.naming.Context.PROVIDER_URL</constant>
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
Any other settings prefixed with <literal>hibernate.jndi.</literal> will be collected
|
||||||
|
and passed along to the JNDI provider.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
</itemizedlist>
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<note>
|
||||||
|
<para>
|
||||||
|
The standard JndiService assumes that all JNDI calls are relative to the same InitialContext. If your
|
||||||
|
application uses multiple naming servers for whatever reason, you will need a custom JndiService
|
||||||
|
implementation to handle those details.
|
||||||
|
</para>
|
||||||
|
</note>
|
||||||
|
</chapter>
|
Loading…
Reference in New Issue