|
|
|
@ -0,0 +1,237 @@
|
|
|
|
|
= Native Bootstrapping
|
|
|
|
|
:toc:
|
|
|
|
|
|
|
|
|
|
This guide discusses the process of bootstrapping a Hibernate `org.hibernate.SessionFactory`. It also
|
|
|
|
|
discusses the ways in which applications and integrators can hook-in to and affect that process. This
|
|
|
|
|
bootstrapping process is defined in 2 distinct steps. The first step is the building of a ServiceRegistry
|
|
|
|
|
holding the services Hibernate will need at bootstrap- and run-time. The second step is the building of
|
|
|
|
|
a Metadata object representing the mapping information for the application's model and its mapping to
|
|
|
|
|
the database.
|
|
|
|
|
|
|
|
|
|
NOTE : Prior to version 5.0 applications bootstrapped a `SessionFactory` is via the
|
|
|
|
|
`org.hibernate.cfg.Configuration` object. That approach is still supported in a slightly limited manner.
|
|
|
|
|
See the _Legacy Bootstrapping_ guide for details.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
== Building the ServiceRegistry
|
|
|
|
|
|
|
|
|
|
Actually we are concerned with building 2 different ServiceRegistries:
|
|
|
|
|
|
|
|
|
|
* `org.hibernate.boot.registry.BootstrapServiceRegistry`
|
|
|
|
|
* `org.hibernate.boot.registry.StandardServiceRegistry`
|
|
|
|
|
|
|
|
|
|
Each of these is built from a builder, `org.hibernate.boot.registry.BootstrapServiceRegistryBuilder`
|
|
|
|
|
and `org.hibernate.boot.registry.StandardServiceRegistryBuilder` respectively.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
NOTE: For more information on ServiceRegistries in general, see the _Services and Registries_ guide.
|
|
|
|
|
|
|
|
|
|
=== BootstrapServiceRegistry
|
|
|
|
|
|
|
|
|
|
The `BootstrapServiceRegistry` is intended to hold services that Hibernate needs at both bootstrap and run time.
|
|
|
|
|
This boils down to 3 services:
|
|
|
|
|
|
|
|
|
|
* `ClassLoaderService` - which controls how Hibernate interacts with ClassLoaders
|
|
|
|
|
* `IntegratorService` - which controls the management ands discovery of `org.hibernate.integrator.spi.Integrator` instances.
|
|
|
|
|
* `StrategySelector` - which control how Hibernate resolves implementations of various strategy
|
|
|
|
|
contracts. This is a very powerful service, but a full discussion of it is beyond the scope
|
|
|
|
|
of this guide.
|
|
|
|
|
|
|
|
|
|
If you are ok with the default behavior of Hibernate in regards to these BootstrapServiceRegistry services
|
|
|
|
|
(which is quite often the case, especially in SE environments) building the BootstrapServiceRegistry can be skipped.
|
|
|
|
|
If you wish to alter how the `BootstrapServiceRegistry` is built, you would use the `BootstrapServiceRegistryBuilder`:
|
|
|
|
|
|
|
|
|
|
[[bootstrap-registry-builder-example]]
|
|
|
|
|
.Building a BootstrapServiceRegistry
|
|
|
|
|
====
|
|
|
|
|
[source, JAVA]
|
|
|
|
|
----
|
|
|
|
|
BootstrapServiceRegistryBuilder bootstrapRegistryBuilder = new BootstrapServiceRegistryBuilder();
|
|
|
|
|
// add a special ClassLoader
|
|
|
|
|
bootstrapRegistryBuilder.with( mySpecialClassLoader );
|
|
|
|
|
// manually add an Integrator
|
|
|
|
|
bootstrapRegistryBuilder.with( mySpecialIntegrator );
|
|
|
|
|
...
|
|
|
|
|
|
|
|
|
|
BootstrapServiceRegistry bootstrapRegistry = bootstrapRegistryBuilder.build();
|
|
|
|
|
----
|
|
|
|
|
====
|
|
|
|
|
|
|
|
|
|
The services of the `BootstrapServiceRegistry` cannot be extended (added to) nor overridden (replaced).
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
=== StandardServiceRegistry
|
|
|
|
|
|
|
|
|
|
The services of the `StandardServiceRegistry` may be extended and overridden.
|
|
|
|
|
|
|
|
|
|
A `StandardServiceRegistry` is built through the `StandardServiceRegistryBuilder` which can be constructed in
|
|
|
|
|
one of 2 ways:
|
|
|
|
|
|
|
|
|
|
[[standard-registry-builder-example1]]
|
|
|
|
|
.Building a StandardServiceRegistryBuilder with a supplied BootstrapServiceRegistry
|
|
|
|
|
====
|
|
|
|
|
[source, JAVA]
|
|
|
|
|
----
|
|
|
|
|
BootstrapServiceRegistry bootstrapRegistry = ...;
|
|
|
|
|
StandardServiceRegistryBuilder standardRegistryBuilder = new StandardServiceRegistryBuilder( bootstrapRegistry );
|
|
|
|
|
----
|
|
|
|
|
====
|
|
|
|
|
|
|
|
|
|
[[standard-registry-builder-example2]]
|
|
|
|
|
.Building a StandardServiceRegistryBuilder without a supplied BootstrapServiceRegistry
|
|
|
|
|
====
|
|
|
|
|
[source, JAVA]
|
|
|
|
|
----
|
|
|
|
|
StandardServiceRegistryBuilder standardRegistryBuilder = new StandardServiceRegistryBuilder();
|
|
|
|
|
----
|
|
|
|
|
====
|
|
|
|
|
|
|
|
|
|
The second form will create a `BootstrapServiceRegistry` on the fly with default behavior.
|
|
|
|
|
|
|
|
|
|
A `StandardServiceRegistry` is also highly configurable via the `StandardServiceRegistryBuilder` API. See the
|
|
|
|
|
`StandardServiceRegistryBuilder` javadocs for full details. Some specific methods of interest:
|
|
|
|
|
|
|
|
|
|
[[standard-registry-builder-example3]]
|
|
|
|
|
.Configuring StandardServiceRegistryBuilder
|
|
|
|
|
====
|
|
|
|
|
[source, JAVA]
|
|
|
|
|
----
|
|
|
|
|
StandardServiceRegistryBuilder standardRegistryBuilder = ...;
|
|
|
|
|
// load some properties via resource lookup
|
|
|
|
|
standardRegistryBuilder.loadProperties( "org/hibernate/example/MyProperties.properties" );
|
|
|
|
|
// configure the registry from a resource lookup for a cfg.xml config file
|
|
|
|
|
standardRegistryBuilder.configure( "org/hibernate/example/MyCfg.xml" );
|
|
|
|
|
// apply a random setting
|
|
|
|
|
standardRegistryBuilder.applySetting( "myProp", "some value" );
|
|
|
|
|
// apply a service initiator
|
|
|
|
|
standardRegistryBuilder.addInitiator( new CustomServiceInitiator() );
|
|
|
|
|
// apply a service impl
|
|
|
|
|
standardRegistryBuilder.addService( SomeCustomService.class, new SomeCustomServiceImpl() );
|
|
|
|
|
|
|
|
|
|
// and finally build the StandardServiceRegistry
|
|
|
|
|
StandardServiceRegistry standardRegistry = standardRegistryBuilder.build();
|
|
|
|
|
----
|
|
|
|
|
====
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
== Building the Metadata
|
|
|
|
|
|
|
|
|
|
The `org.hibernate.boot.Metadata` object contains the parsed representations of an application's
|
|
|
|
|
domain model and its mapping to a database. The first thing we obviously need to build a parsed
|
|
|
|
|
representation is the source information to be parsed. This is the purpose of
|
|
|
|
|
`org.hibernate.boot.MetadataSources`.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
[[MetadataSources-example]]
|
|
|
|
|
.Configuring a MetadataSources
|
|
|
|
|
====
|
|
|
|
|
[source, JAVA]
|
|
|
|
|
----
|
|
|
|
|
MetadataSources sources = new MetadataSources( standardRegistry );
|
|
|
|
|
// alternatively, we can build the MetadataSources without passing
|
|
|
|
|
// a service registry, in which case it will build a default
|
|
|
|
|
// BootstrapServiceRegistry to use
|
|
|
|
|
// MetadataSources sources = new MetadataSources();
|
|
|
|
|
|
|
|
|
|
// add a class using JPA/Hibernate annotations for mapping
|
|
|
|
|
sources.addAnnotatedClass( MyEntity.class );
|
|
|
|
|
|
|
|
|
|
// add the name of a class using JPA/Hibernate annotations for mapping.
|
|
|
|
|
// differs from above in that accessing the Class is deferred which is
|
|
|
|
|
// important if using runtime bytecode-enhancement
|
|
|
|
|
sources.addAnnotatedClassName( "org.hibernate.example.Customer" );
|
|
|
|
|
|
|
|
|
|
// Adds the named hbm.xml resource as a source: which performs the
|
|
|
|
|
// classpath lookup and parses the XML
|
|
|
|
|
sources.addResource( "org/hibernate/example/Order.hbm.xml" );
|
|
|
|
|
|
|
|
|
|
// Adds the named JPA orm.xml resource as a source: which performs the
|
|
|
|
|
// classpath lookup and parses the XML
|
|
|
|
|
sources.addResource( "org/hibernate/example/Product.orm.xml" );
|
|
|
|
|
----
|
|
|
|
|
====
|
|
|
|
|
|
|
|
|
|
`MetadataSources` has many other methods as well; explore its API and javadocs for more information. Also,
|
|
|
|
|
all methods on `MetadataSources` allow for chaining should you prefer that style.
|
|
|
|
|
|
|
|
|
|
[[MetadataSources-chaining-example]]
|
|
|
|
|
.Configuring a MetadataSources with method chaining
|
|
|
|
|
====
|
|
|
|
|
[source, JAVA]
|
|
|
|
|
----
|
|
|
|
|
MetadataSources sources = new MetadataSources( standardRegistry )
|
|
|
|
|
.addAnnotatedClass( MyEntity.class )
|
|
|
|
|
.addAnnotatedClassName( "org.hibernate.example.Customer" )
|
|
|
|
|
.addResource( "org/hibernate/example/Order.hbm.xml" )
|
|
|
|
|
.addResource( "org/hibernate/example/Product.orm.xml" );
|
|
|
|
|
----
|
|
|
|
|
====
|
|
|
|
|
|
|
|
|
|
Once we have the sources of mapping information defined, we need to build the `Metadata` object. If you are
|
|
|
|
|
ok with the default behavior in building the `Metadata` (or if relying on a `MetadataBuilderContributor` - see below)
|
|
|
|
|
then you can simply call `MetadataSources#buildMetadata`.
|
|
|
|
|
|
|
|
|
|
NOTE : Notice that a ServiceRegistry can be passed at a number of points in this bootstrapping process. The suggested
|
|
|
|
|
approach is to build a `StandardServiceRegistry` yourself and pass that along to the `MetadataSources` constructor.
|
|
|
|
|
From there, `MetadataBuilder`, `Metadata`, `SessionFactoryBuilder` and `SessionFactory` will all pick up that
|
|
|
|
|
same `StandardServiceRegistry`.
|
|
|
|
|
|
|
|
|
|
However, if you wish to adjust the process of building `Metadata` from `MetadataSources` you will need to use
|
|
|
|
|
the `MetadataBuilder` as obtained via `MetadataSources#getMetadataBuilder`. `MetadataBuilder` allows a lot of control
|
|
|
|
|
over the `Metadata` building process. See its javadocs for full details.
|
|
|
|
|
|
|
|
|
|
[[MetadataBuilder-example]]
|
|
|
|
|
.Building Metadata via MetadataBuilder
|
|
|
|
|
====
|
|
|
|
|
[source, JAVA]
|
|
|
|
|
----
|
|
|
|
|
MetadataBuilder metadataBuilder = sources.getMetadataBuilder();
|
|
|
|
|
|
|
|
|
|
// Use the JPA-compliant implicit naming strategy
|
|
|
|
|
metadataBuilder.with( ImplicitNamingStrategyJpaCompliantImpl.INSTANCE );
|
|
|
|
|
|
|
|
|
|
// specify the schema name to use for tables, etc when none is explicitly specified
|
|
|
|
|
metadataBuilder.withImplicitSchemaName( "my_default_schema" );
|
|
|
|
|
|
|
|
|
|
Metadata metadata = metadataBuilder.build();
|
|
|
|
|
----
|
|
|
|
|
====
|
|
|
|
|
|
|
|
|
|
== Building the SessionFactory
|
|
|
|
|
|
|
|
|
|
Much like we've discussed above, if you are ok with the default behavior of building a `SessionFactory`
|
|
|
|
|
from a `Metadata` reference, you can simply call `Metadata#buildSessionFactory`. However, if you would like to
|
|
|
|
|
adjust that building process you will need to use `SessionFactoryBuilder` as obtained via
|
|
|
|
|
`Metadata#getSessionFactoryBuilder`. See the `SessionFactoryBuilder` javadocs for details of the control it allows
|
|
|
|
|
over the `SessionFactory` building process.
|
|
|
|
|
|
|
|
|
|
[[SessionFactoryBuilder-example]]
|
|
|
|
|
.Building SessionFactory via SessionFactoryBuilder
|
|
|
|
|
====
|
|
|
|
|
[source, JAVA]
|
|
|
|
|
----
|
|
|
|
|
SessionFactoryBuilder sessionFactoryBuilder = metadata.getSessionFactoryBuilder();
|
|
|
|
|
|
|
|
|
|
// Supply an SessionFactory-level Interceptor
|
|
|
|
|
sessionFactoryBuilder.with( new MySessionFactoryInterceptor() );
|
|
|
|
|
|
|
|
|
|
// Add a custom observer
|
|
|
|
|
sessionFactoryBuilder.add( new MySessionFactoryObserver() );
|
|
|
|
|
|
|
|
|
|
// Apply a CDI BeanManager (for JPA event listeners)
|
|
|
|
|
sessionFactoryBuilder.withBeanManager( getBeanManagerFromSomewhere() );
|
|
|
|
|
|
|
|
|
|
SessionFactory sessionFactory = sessionFactoryBuilder.build();
|
|
|
|
|
----
|
|
|
|
|
====
|
|
|
|
|
|
|
|
|
|
== Putting It All Together
|
|
|
|
|
|
|
|
|
|
== Integration Points
|
|
|
|
|
|
|
|
|
|
=== Integrator
|
|
|
|
|
=== ServiceContributor
|
|
|
|
|
=== TypeContributor
|
|
|
|
|
=== MetadataSourcesContributor
|
|
|
|
|
=== MetadataBuilderContributor
|
|
|
|
|
=== SessionFactoryBuilderContributor (todo)
|