HHH-15170 - Dedicated chapter for "Build Tool Support"
HHH-15171 - Add discussion of the Ant Plugin
This commit is contained in:
parent
17bb4aa066
commit
84cf4524ea
|
@ -1,63 +0,0 @@
|
||||||
[[jpa-bootstrap-guide]]
|
|
||||||
= Bootstrapping Hibernate Jakarta Persistence
|
|
||||||
:toc:
|
|
||||||
|
|
||||||
Bootstrapping Hibernate as a Jakarta Persistence provider can be done in a Jakarta Persistence-spec compliant manner or using a proprietary
|
|
||||||
bootstrapping approach. The standardized approach has some limitations in certain environments. But aside from
|
|
||||||
those limitations, it is *highly* recommended that you use Jakarta Persistence-standardized bootstrapping.
|
|
||||||
|
|
||||||
NOTE: Under the covers, all of Hibernate's Jakarta Persistence bootstrapping makes use of its native bootstrapping. Be sure to see
|
|
||||||
the _Native Bootstrapping_ guide as well.
|
|
||||||
|
|
||||||
== Jakarta Persistence compliant bootstrapping
|
|
||||||
|
|
||||||
In Jakarta Persistence we are ultimately interested in bootstrapping an `jakarta.persistence.EntityManagerFactory` instance. The
|
|
||||||
Jakarta Persistence specification defines 2 primary standardized bootstrap approaches depending on how the application intends to
|
|
||||||
access the `jakarta.persistence.EntityManager` instances from an `EntityManagerFactory`. It uses the terms "EE" and
|
|
||||||
"SE" for these 2 approaches, but those terms are very misleading in this context. What the Jakarta Persistence spec calls EE
|
|
||||||
bootstrapping is cases where a container (EE, OSGi, etc) will manage and inject the persistence context on behalf
|
|
||||||
of the application. What it calls SE bootstrapping is everything else. We will use the terms
|
|
||||||
container-bootstrapping and application-bootstrapping in this guide.
|
|
||||||
|
|
||||||
NOTE: If you would like additional details on accessing and using `EntityManager` instances, sections 7.6
|
|
||||||
and 7.7 of the Jakarta Persistence specification cover container-managed and application-managed EntityManagers,
|
|
||||||
respectively.
|
|
||||||
|
|
||||||
|
|
||||||
=== Container-bootstrapping
|
|
||||||
|
|
||||||
The container will build an `EntityManagerFactory` for each persistent-unit defined in the deployment's
|
|
||||||
`META-INF/persistence.xml` and make that available to the application for injection via the
|
|
||||||
`jakarta.persistence.PersistenceUnit` annotation or via JNDI lookup.
|
|
||||||
|
|
||||||
[[container-bootstrap-injection-example]]
|
|
||||||
.Injecting a EntityManagerFactory
|
|
||||||
====
|
|
||||||
[source, JAVA]
|
|
||||||
----
|
|
||||||
@PersistenceUnit
|
|
||||||
EntityManagerFactory emf;
|
|
||||||
----
|
|
||||||
====
|
|
||||||
|
|
||||||
|
|
||||||
=== Application-bootstrapping
|
|
||||||
|
|
||||||
Rather than something a container building the `EntityManagerFactory` for the application, the application
|
|
||||||
can build the `EntityManagerFactory` using the `jakarta.persistence.Persistence` bootstrap class. The application
|
|
||||||
creates an entity manager factory by calling the createEntityManagerFactory method:
|
|
||||||
|
|
||||||
[[application-bootstrap-example]]
|
|
||||||
.Application bootstrapped EntityManagerFactory
|
|
||||||
====
|
|
||||||
[source, JAVA]
|
|
||||||
----
|
|
||||||
// Create an EMF for our CRM persistence-unit.
|
|
||||||
EntityManagerFactory emf = Persistence.createEntityManagerFactory("CRM");
|
|
||||||
----
|
|
||||||
====
|
|
||||||
|
|
||||||
|
|
||||||
== Proprietary 2-phase bootstrapping
|
|
||||||
|
|
||||||
todo: document EntityManagerFactoryBuilder...
|
|
|
@ -1,127 +0,0 @@
|
||||||
[[legacy-boostrap-guide]]
|
|
||||||
= Legacy Bootstrapping
|
|
||||||
:toc:
|
|
||||||
|
|
||||||
The legacy way to bootstrap a `SessionFactory` is via the `org.hibernate.cfg.Configuration` object.
|
|
||||||
`Configuration` represents, essentially, a single point for specifying all aspects of building
|
|
||||||
the `SessionFactory`: everything from settings, to mappings, to strategies, etc. I like to think of
|
|
||||||
`Configuration` as a big pot to which we add a bunch of stuff (mappings, settings, etc) and from which
|
|
||||||
we eventually get a `SessionFactory`.
|
|
||||||
|
|
||||||
NOTE: There are some significant draw backs to this approach which led to its deprecation and the development
|
|
||||||
of the new approach, which is discussed in the _Native Bootstrapping_ guide. `Configuration` is deprecated but
|
|
||||||
still available for use, in a limited form that eliminates these draw backs. "Under the covers", Configuration
|
|
||||||
uses the new bootstrapping code, so the things available there as also available here in terms of
|
|
||||||
auto-discovery.
|
|
||||||
|
|
||||||
|
|
||||||
== Usage
|
|
||||||
|
|
||||||
You can obtain the `Configuration` by instantiating it directly. You then specify mapping metadata (XML
|
|
||||||
mapping documents, annotated classes) that describe your applications object model and its mapping to a
|
|
||||||
SQL database.
|
|
||||||
|
|
||||||
If XML mapping files are in the classpath, use addResource(). For example:
|
|
||||||
|
|
||||||
====
|
|
||||||
[source, JAVA]
|
|
||||||
----
|
|
||||||
Configuration cfg = new Configuration()
|
|
||||||
// addResource does a classpath resource lookup
|
|
||||||
.addResource("Item.hbm.xml")
|
|
||||||
.addResource("Bid.hbm.xml")
|
|
||||||
|
|
||||||
// calls addResource using "/org/hibernate/auction/User.hbm.xml"
|
|
||||||
.addClass(`org.hibernate.auction.User.class`)
|
|
||||||
|
|
||||||
// parses Address class for mapping annotations
|
|
||||||
.addAnnotatedClass( Address.class )
|
|
||||||
|
|
||||||
// reads package-level (package-info.class) annotations in the named package
|
|
||||||
.addPackage( "org.hibernate.auction" )
|
|
||||||
----
|
|
||||||
====
|
|
||||||
|
|
||||||
`Configuration` also allows you to specify configuration properties. For example:
|
|
||||||
|
|
||||||
====
|
|
||||||
[source, JAVA]
|
|
||||||
----
|
|
||||||
Configuration cfg = new Configuration()
|
|
||||||
.setProperty("hibernate.dialect", "org.hibernate.dialect.H2Dialect")
|
|
||||||
.setProperty("hibernate.connection.datasource", "java:comp/env/jdbc/test")
|
|
||||||
.setProperty("hibernate.order_updates", "true");
|
|
||||||
----
|
|
||||||
====
|
|
||||||
|
|
||||||
There are other ways to specify configuration properties, including:
|
|
||||||
|
|
||||||
* Place a file named hibernate.properties in a root directory of the classpath.
|
|
||||||
* Place a file named hibernate.properties in a root directory of the classpath.
|
|
||||||
* Pass an instance of java.util.Properties to `Configuration#setProperties`.
|
|
||||||
* Set System properties using Java `-Dproperty=value`.
|
|
||||||
* Include `<property/>` elements in `hibernate.cfg.xml`
|
|
||||||
|
|
||||||
|
|
||||||
== Migration
|
|
||||||
|
|
||||||
Mapping Configuration methods to the corresponding methods in the new API..
|
|
||||||
|
|
||||||
=== Mapping metadata
|
|
||||||
|
|
||||||
`Configuration#addFile`::
|
|
||||||
`MetadataSources#addFile`
|
|
||||||
`Configuration#add(XmlDocument)`::
|
|
||||||
No replacement.
|
|
||||||
`Configuration#addXML`::
|
|
||||||
No replacement.
|
|
||||||
`Configuration#addCacheableFile`::
|
|
||||||
`MetadataSources#addCacheableFile`
|
|
||||||
`Configuration#addURL`::
|
|
||||||
`MetadataSources#addURL`
|
|
||||||
`Configuration#addInputStream`::
|
|
||||||
`MetadataSources#addInputStream`
|
|
||||||
`Configuration#addResource`::
|
|
||||||
`MetadataSources#addResource`
|
|
||||||
`Configuration#addClass`::
|
|
||||||
`MetadataSources#addClass`
|
|
||||||
`Configuration#addAnnotatedClass`::
|
|
||||||
`MetadataSources#addAnnotatedClass`
|
|
||||||
`Configuration#addPackage`::
|
|
||||||
`MetadataSources#addPackage`
|
|
||||||
`Configuration#addJar`::
|
|
||||||
`MetadataSources#addJar`
|
|
||||||
`Configuration#addDirectory`::
|
|
||||||
`MetadataSources#addDirectory`
|
|
||||||
|
|
||||||
`Configuration#registerTypeContributor`::
|
|
||||||
`MetadataBuilder#applyTypes`
|
|
||||||
`Configuration#registerTypeOverride`::
|
|
||||||
`MetadataBuilder#applyBasicType`
|
|
||||||
|
|
||||||
=== Settings
|
|
||||||
|
|
||||||
`Configuration#setProperty`::
|
|
||||||
`StandardServiceRegistryBuilder#applySetting`
|
|
||||||
`Configuration#setProperties`::
|
|
||||||
No replacement.
|
|
||||||
`Configuration#addProperties`::
|
|
||||||
`StandardServiceRegistryBuilder#applySettings`
|
|
||||||
`Configuration#setNamingStrategy`::
|
|
||||||
No replacement. NamingStrategy split into implicit/physical strategies
|
|
||||||
`Configuration#setImplicitNamingStrategy`::
|
|
||||||
`MetadataBuilder#setImplicitNamingStrategy`
|
|
||||||
`Configuration#setPhysicalNamingStrategy`::
|
|
||||||
`MetadataBuilder#setPhysicalNamingStrategy`
|
|
||||||
`Configuration#configure`::
|
|
||||||
`StandardServiceRegistryBuilder#configure`
|
|
||||||
|
|
||||||
`Configuration#setInterceptor`::
|
|
||||||
`SessionFactoryBuilder#applyInterceptor`
|
|
||||||
`Configuration#setEntityNotFoundDelegate`::
|
|
||||||
`SessionFactoryBuilder#applyEntityNotFoundDelegate`
|
|
||||||
`Configuration#setSessionFactoryObserver`::
|
|
||||||
`SessionFactoryBuilder#addSessionFactoryObservers`
|
|
||||||
`Configuration#setCurrentTenantIdentifierResolver`::
|
|
||||||
`SessionFactoryBuilder#applyCurrentTenantIdentifierResolver`
|
|
||||||
|
|
|
@ -1,274 +0,0 @@
|
||||||
[[native-bootstrap]]
|
|
||||||
= 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 runtime. 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.applyClassLoader( mySpecialClassLoader );
|
|
||||||
// manually add an Integrator
|
|
||||||
bootstrapRegistryBuilder.applyIntegrator( 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 (annotated classes, `hbm.xml` files, `orm.xml` files). 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 annotations for mapping
|
|
||||||
sources.addAnnotatedClass( MyEntity.class );
|
|
||||||
|
|
||||||
// add the name of a class using 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 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 `MetadataBuilderInitializer` - 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 Jakarta Persistence-compliant implicit naming strategy
|
|
||||||
metadataBuilder.applyImplicitNamingStrategy( ImplicitNamingStrategyJpaCompliantImpl.INSTANCE );
|
|
||||||
|
|
||||||
// specify the schema name to use for tables, etc when none is explicitly specified
|
|
||||||
metadataBuilder.applyImplicitSchemaName( "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 a SessionFactory-level Interceptor
|
|
||||||
sessionFactoryBuilder.applyInterceptor( new MySessionFactoryInterceptor() );
|
|
||||||
|
|
||||||
// Add a custom observer
|
|
||||||
sessionFactoryBuilder.addSessionFactoryObservers( new MySessionFactoryObserver() );
|
|
||||||
|
|
||||||
// Apply a CDI BeanManager (for Jakarta Persistence event listeners)
|
|
||||||
sessionFactoryBuilder.applyBeanManager( getBeanManagerFromSomewhere() );
|
|
||||||
|
|
||||||
SessionFactory sessionFactory = sessionFactoryBuilder.build();
|
|
||||||
----
|
|
||||||
====
|
|
||||||
|
|
||||||
== Putting It All Together
|
|
||||||
|
|
||||||
The bootstrapping API is quite flexible, but in most cases it makes the most sense to think of
|
|
||||||
it as a 3 step process:
|
|
||||||
|
|
||||||
1. Build the `StandardServiceRegistry`
|
|
||||||
2. Build the `Metadata`
|
|
||||||
3. Use those 2 things to build the `SessionFactory`
|
|
||||||
|
|
||||||
[[Putting-It-All-Together-ex1]]
|
|
||||||
.Building SessionFactory via SessionFactoryBuilder
|
|
||||||
====
|
|
||||||
[source, JAVA]
|
|
||||||
----
|
|
||||||
StandardServiceRegistry standardRegistry = new StandardServiceRegistryBuilder()
|
|
||||||
.configure( "org/hibernate/example/MyCfg.xml" )
|
|
||||||
.build();
|
|
||||||
|
|
||||||
Metadata metadata = 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" )
|
|
||||||
.getMetadataBuilder()
|
|
||||||
.applyImplicitNamingStrategy( ImplicitNamingStrategyJpaCompliantImpl.INSTANCE )
|
|
||||||
.build();
|
|
||||||
|
|
||||||
SessionFactory sessionFactory = metadata.getSessionFactoryBuilder()
|
|
||||||
.applyBeanManager( getBeanManagerFromSomewhere() )
|
|
||||||
.build();
|
|
||||||
----
|
|
||||||
====
|
|
||||||
|
|
||||||
|
|
||||||
== Integration Points
|
|
||||||
|
|
||||||
=== Integrator
|
|
||||||
=== ServiceContributor
|
|
||||||
=== TypeContributor
|
|
||||||
=== MetadataSourcesContributor
|
|
||||||
=== MetadataBuilderInitializer
|
|
||||||
=== SessionFactoryBuilderInitializer (todo)
|
|
||||||
=== SessionFactoryObserver
|
|
|
@ -1,162 +0,0 @@
|
||||||
[[bytecode-enhancement-guide]]
|
|
||||||
= Bytecode Enhancement
|
|
||||||
:toc:
|
|
||||||
|
|
||||||
This guide covers Hibernate's ability to enhance an applications domain model, the ways to perform that
|
|
||||||
enhancement and the capabilities introduced into the domain model by the enhancement.
|
|
||||||
|
|
||||||
== The capabilities
|
|
||||||
|
|
||||||
Hibernate will enhance the classes in an application's domain model in order to add one or more of the
|
|
||||||
following capabilities:
|
|
||||||
|
|
||||||
. Lazy state initialization
|
|
||||||
. Dirtiness tracking
|
|
||||||
. Automatic bi-directional association management
|
|
||||||
. Performance optimizations
|
|
||||||
|
|
||||||
todo : explain each in detail
|
|
||||||
|
|
||||||
|
|
||||||
== Performing enhancement
|
|
||||||
|
|
||||||
Ultimately all enhancement is handled by the `org.hibernate.bytecode.enhance.spi.Enhancer` class. Custom means to
|
|
||||||
enhancement can certainly be crafted on top of Enhancer, but that is beyond the scope of this guide. Here we
|
|
||||||
will focus on the means Hibernate already exposes for performing these enhancements.
|
|
||||||
|
|
||||||
=== Runtime enhancement
|
|
||||||
|
|
||||||
Currently runtime enhancement of the domain model is only supported in managed Jakarta Persistence environments following the Jakarta Persistence defined SPI for performing class transformations.
|
|
||||||
|
|
||||||
Even then, this support is disabled by default. To enable runtime enhancement, specify one of the following configuration properties:
|
|
||||||
|
|
||||||
`*hibernate.enhancer.enableDirtyTracking*` (e.g. `true` or `false` (default value))::
|
|
||||||
Enable dirty tracking feature in runtime bytecode enhancement.
|
|
||||||
|
|
||||||
`*hibernate.enhancer.enableLazyInitialization*` (e.g. `true` or `false` (default value))::
|
|
||||||
Enable lazy loading feature in runtime bytecode enhancement. This way, even basic types (e.g. `@Basic(fetch = FetchType.LAZY`)) can be fetched lazily.
|
|
||||||
|
|
||||||
`*hibernate.enhancer.enableAssociationManagement*` (e.g. `true` or `false` (default value))::
|
|
||||||
Enable association management feature in runtime bytecode enhancement which automatically synchronizes a bidirectional association when only one side is changed.
|
|
||||||
|
|
||||||
|
|
||||||
=== Build-time enhancement
|
|
||||||
|
|
||||||
Hibernate also offers the ability to integrate the enhancement of the domain model as part of the
|
|
||||||
normal build cycle of that domain model. Gradle, Ant and Maven are all supported. One possible benefit
|
|
||||||
of this approach is that the enhanced classes are what gets added to the jar and can then be used on both
|
|
||||||
sides of serialization.
|
|
||||||
|
|
||||||
=== Gradle Plugin
|
|
||||||
|
|
||||||
Hibernate provides a Gradle plugin that is capable of providing build-time enhancement of the domain model as they are
|
|
||||||
compiled as part of a Gradle build. To use the plugin a project would first need to apply it:
|
|
||||||
|
|
||||||
[[gradle-plugin-apply-example]]
|
|
||||||
.Apply the plugin
|
|
||||||
====
|
|
||||||
[source, GROOVY]
|
|
||||||
----
|
|
||||||
buildscript {
|
|
||||||
repositories {
|
|
||||||
mavenLocal()
|
|
||||||
mavenCentral()
|
|
||||||
}
|
|
||||||
dependencies {
|
|
||||||
classpath "org.hibernate:hibernate-gradle-plugin:5.1.0.Final"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
apply plugin: 'org.hibernate.orm'
|
|
||||||
----
|
|
||||||
====
|
|
||||||
|
|
||||||
At the moment there is not much to configure with regard to the Enhancer, but what is configurable is exposed through a DSL extension registered.
|
|
||||||
By default, enhancement will not be done (in preparation for when this Gradle plugin offers additional capabilities).
|
|
||||||
To enable it you must configure the following DSL extension:
|
|
||||||
|
|
||||||
[[gradle-plugin-apply-example]]
|
|
||||||
.Apply the plugin
|
|
||||||
====
|
|
||||||
[source, GROOVY]
|
|
||||||
----
|
|
||||||
hibernate {
|
|
||||||
enhance {
|
|
||||||
enableLazyInitialization= true
|
|
||||||
enableDirtyTracking = true
|
|
||||||
enableAssociationManagement = true
|
|
||||||
enableExtendedEnhancement = false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
----
|
|
||||||
====
|
|
||||||
|
|
||||||
Currently the "enhance" extension supports 4 properties:
|
|
||||||
|
|
||||||
* `enableLazyInitialization`
|
|
||||||
* `enableDirtyTracking`
|
|
||||||
* `enableAssociationManagement`
|
|
||||||
* `enableExtendedEnhancement`
|
|
||||||
|
|
||||||
Once enhancement overall is enabled, the default for the first 3 properties is `true`. Field access is not enhanced by
|
|
||||||
default, as it can potentially trigger enhancement of code outside the entities, and also because it assumes that all
|
|
||||||
the target entities are enhanced, which may not always be the case.
|
|
||||||
|
|
||||||
=== Maven Plugin
|
|
||||||
|
|
||||||
The Hibernate Maven plugin provides a convenient way to enhance the domain model at build-time when using Maven as the
|
|
||||||
build environment. Much like the Gradle plugin, the current bytecode enhancement capabilities that can be configured
|
|
||||||
on the plugin are:
|
|
||||||
|
|
||||||
* `enableLazyInitialization`
|
|
||||||
* `enableDirtyTracking`
|
|
||||||
* `enableAssociationManagement`
|
|
||||||
* `enableExtendedEnhancement`
|
|
||||||
|
|
||||||
Field access is not enhanced by default, because it can potentially trigger enhancement of code outside the entities.
|
|
||||||
Other capabilities are enabled by default. Even if the plugin is enabled, the bytecode enhancement can be bypassed by
|
|
||||||
disabling all the capabilities.
|
|
||||||
|
|
||||||
There is also a parameter `failOnError` that controls what happens in case of error. Default behavior is to fail the
|
|
||||||
build, but it can be set so that only a warning is issued.
|
|
||||||
|
|
||||||
To use the Hibernate Maven plugin on a build it must added to the model (pom.xml) along with other plugins that may be
|
|
||||||
already in use. The XML snippet below is an example of how to declare and configure the plugin.
|
|
||||||
|
|
||||||
[[maven-plugin-apply-example]]
|
|
||||||
.Apply the plugin
|
|
||||||
====
|
|
||||||
[source, XML]
|
|
||||||
----
|
|
||||||
<build>
|
|
||||||
<plugins>
|
|
||||||
[...]
|
|
||||||
<plugin>
|
|
||||||
<groupId>org.hibernate.orm.tooling</groupId>
|
|
||||||
<artifactId>hibernate-enhance-maven-plugin</artifactId>
|
|
||||||
<version>$currentHibernateVersion</version>
|
|
||||||
<executions>
|
|
||||||
<execution>
|
|
||||||
<configuration>
|
|
||||||
<failOnError>true</failOnError>
|
|
||||||
<enableLazyInitialization>true</enableLazyInitialization>
|
|
||||||
<enableDirtyTracking>true</enableDirtyTracking>
|
|
||||||
<enableAssociationManagement>true</enableAssociationManagement>
|
|
||||||
<enableExtendedEnhancement>false</enableExtendedEnhancement>
|
|
||||||
</configuration>
|
|
||||||
<goals>
|
|
||||||
<goal>enhance</goal>
|
|
||||||
</goals>
|
|
||||||
</execution>
|
|
||||||
</executions>
|
|
||||||
</plugin>
|
|
||||||
[...]
|
|
||||||
</plugins>
|
|
||||||
</build>
|
|
||||||
----
|
|
||||||
====
|
|
||||||
|
|
||||||
=== Ant Task
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,95 +0,0 @@
|
||||||
[[logging-guide]]]]
|
|
||||||
= Logging Guide
|
|
||||||
:toc:
|
|
||||||
|
|
||||||
Since version 4.0, Hibernate has used the JBoss Logging library for its logging needs. Like SLF4J and
|
|
||||||
Jakarta's commons-logging, JBoss Logging is a "logging bridge" providing integration with numerous logging
|
|
||||||
frameworks. JBoss Logging was chosen because of its i18n support and its support for "message ids". This is largely
|
|
||||||
the seminal documentation of JBoss Logging since JBoss Logging currently provides no documentation of its own.
|
|
||||||
|
|
||||||
|
|
||||||
== Supported Back-ends
|
|
||||||
|
|
||||||
JBoss Logging understands the following back-ends as first-class citizens:
|
|
||||||
|
|
||||||
. JBoss LogManager (mainly used only inside the WildFly app server)
|
|
||||||
. Log4j 2
|
|
||||||
. Log4j 1
|
|
||||||
. Slf4j
|
|
||||||
. JDK logging
|
|
||||||
|
|
||||||
Note the order above, it is important. By default JBoss Logging will search the ClassLoader for the availability of
|
|
||||||
classes that indicate one of the above "providers" being available. It does this in the order defined above. So,
|
|
||||||
for example, if you have both JBoss LogManager and Slf4j available your classpath then JBoss LogManager will be used
|
|
||||||
as it has the "higher precedence".
|
|
||||||
|
|
||||||
NOTE: Slf4j will only be auto-selected if Logback is in use.
|
|
||||||
|
|
||||||
This can sometimes lead to an unwanted logging set up to be used. In such cases, JBoss Logging provides for you to
|
|
||||||
tell it specifically which provider to use and circumvent the discovery process just described. It allows 2 different
|
|
||||||
mechanisms for this:
|
|
||||||
|
|
||||||
. First, JBoss Logging will look for a *System* setting with the key `org.jboss.logging.provider`, which can be set to
|
|
||||||
one of the following values:
|
|
||||||
|
|
||||||
* jboss
|
|
||||||
* jdk
|
|
||||||
* log4j2
|
|
||||||
* log4j
|
|
||||||
* slf4j
|
|
||||||
|
|
||||||
. Next, JBoss Logging will look for a JDK service (see javadocs for +java.util.ServiceLoader+ for details) for its
|
|
||||||
"provider" contract (+org.jboss.logging.Provider+). If multiple are available, it will use the first one returned by
|
|
||||||
the ClassLoader.
|
|
||||||
|
|
||||||
|
|
||||||
== Usage
|
|
||||||
|
|
||||||
Most of the time, the discovery process JustWorks. The discovery process relies on the jars available on the classpath.
|
|
||||||
The jboss-logging jar is a required dependency of Hibernate and therefore will always need to be on the classpath.
|
|
||||||
|
|
||||||
* To use JBoss Logging with Log4j, the log4j jar would also need to be available on the classpath.
|
|
||||||
* To use JBoss Logging with Log4j2, the log4j2 jar would also need to be available on the classpath.
|
|
||||||
* To use JBoss Logging with Slf4j, the slf4j-api jar would also need to be available on the classpath *plus* any needed
|
|
||||||
slf4j backend.
|
|
||||||
|
|
||||||
JDK Logging would be used if none of the other framework jars are available.
|
|
||||||
|
|
||||||
|
|
||||||
== Log Categories of Interest
|
|
||||||
|
|
||||||
It is recommended that you familiarize yourself with the log messages sent from Hibernate. A lot of work has been put
|
|
||||||
into making the Hibernate logging as detailed as possible, without making it unreadable. It is an essential
|
|
||||||
troubleshooting device. Some log categories of particular interest include:
|
|
||||||
|
|
||||||
.Hibernate Log Categories of Interest
|
|
||||||
|===
|
|
||||||
|Category|Description
|
|
||||||
|
|
||||||
|org.hibernate.SQL
|
|
||||||
|Log all SQL statements as they are executed with through JDBC
|
|
||||||
|
|
||||||
|org.hibernate.type.descriptor.jdbc
|
|
||||||
|Log all values as they are bound to JDBC parameters and extracted from JDBC results
|
|
||||||
|
|
||||||
|org.hibernate.tool.hbm2ddl
|
|
||||||
|Log all SQL DDL statements as they are executed during execution of any of the schema migration tools
|
|
||||||
|
|
||||||
|org.hibernate.pretty
|
|
||||||
|Log the state of all entities (max 20 entities) associated with the session at flush time
|
|
||||||
|
|
||||||
|org.hibernate.cache
|
|
||||||
|Log all second-level cache activity
|
|
||||||
|
|
||||||
|org.hibernate.hql.internal.ast.AST
|
|
||||||
|Log HQL and SQL ASTs during query parsing
|
|
||||||
|
|
||||||
|org.hibernate
|
|
||||||
|Log everything. This is a lot of information but it is useful for troubleshooting
|
|
||||||
|===
|
|
||||||
|
|
||||||
|
|
||||||
== Message Id Index
|
|
||||||
|
|
||||||
Coming soon.
|
|
||||||
|
|
Loading…
Reference in New Issue