HHH-15170 - Dedicated chapter for "Build Tool Support"
HHH-15171 - Add discussion of the Ant Plugin
This commit is contained in:
parent
cf152d57b1
commit
17bb4aa066
|
@ -1,442 +0,0 @@
|
|||
[[jpamodelgen-guide]]
|
||||
= Jakarta Persistence Static Metamodel Generator
|
||||
:imagesdir: images
|
||||
:version: {fullVersion}
|
||||
:toc:
|
||||
|
||||
[[whatisit]]
|
||||
== What is it about?
|
||||
|
||||
Jakarta Persistence defines a typesafe Criteria API which allows `Criteria` queries
|
||||
to be constructed in a strongly-typed manner, utilizing so called
|
||||
static metamodel classes.
|
||||
For developers it is important that the task of the metamodel generation
|
||||
can be automated.
|
||||
Hibernate Static Metamodel Generator is an annotation processor based on
|
||||
https://jcp.org/en/jsr/detail?id=269[JSR_269] with the task of creating Jakarta Persistence 2
|
||||
static metamodel classes.
|
||||
The following example shows two native-bootstrap entities `Order` and `Item`, together
|
||||
with the metamodel class `Order_` and a typesafe query.
|
||||
|
||||
[[jpa2-entity-example]]
|
||||
.Jakarta Persistence annotated entities `Order` and `Item`
|
||||
|
||||
====
|
||||
[source, JAVA]
|
||||
----
|
||||
|
||||
@Entity
|
||||
public class Order {
|
||||
@Id
|
||||
@GeneratedValue
|
||||
Integer id;
|
||||
|
||||
@ManyToOne
|
||||
Customer customer;
|
||||
|
||||
@OneToMany
|
||||
Set<Item> items;
|
||||
BigDecimal totalCost;
|
||||
|
||||
// standard setter/getter methods
|
||||
...
|
||||
}
|
||||
|
||||
@Entity
|
||||
public class Item {
|
||||
@Id
|
||||
@GeneratedValue
|
||||
Integer id;
|
||||
|
||||
int quantity;
|
||||
|
||||
@ManyToOne
|
||||
Order order;
|
||||
|
||||
// standard setter/getter methods
|
||||
...
|
||||
}
|
||||
|
||||
----
|
||||
|
||||
====
|
||||
[[metamodel-class-example]]
|
||||
.Metamodel class Order_
|
||||
|
||||
====
|
||||
[source, JAVA]
|
||||
----
|
||||
|
||||
@StaticMetamodel(Order.class)
|
||||
public class Order_ {
|
||||
public static volatile SingularAttribute<Order, Integer> id;
|
||||
public static volatile SingularAttribute<Order, Customer> customer;
|
||||
public static volatile SetAttribute<Order, Item> items;
|
||||
public static volatile SingularAttribute<Order, BigDecimal> totalCost;
|
||||
}
|
||||
|
||||
----
|
||||
|
||||
====
|
||||
[[criteria-example]]
|
||||
.Typesafe citeria query
|
||||
|
||||
====
|
||||
[source, JAVA]
|
||||
----
|
||||
CriteriaBuilder cb = entityManager.getCriteriaBuilder();
|
||||
|
||||
CriteriaQuery<Order> cq = cb.createQuery(Order.class);
|
||||
|
||||
SetJoin<Order, Item> itemNode = cq.from(Order.class).join(Order_.items);
|
||||
|
||||
cq.where( cb.equal(itemNode.get(Item_.id), 5 ) ).distinct(true);
|
||||
----
|
||||
|
||||
====
|
||||
|
||||
[TIP]
|
||||
====
|
||||
Hibernate Static Metamodel Generator also takes into consideration xml
|
||||
configuration specified in `orm.xml` or mapping files specified in
|
||||
`persistence.xml`. However, if XML is your only configuration source,
|
||||
you need to add in at least on of the mapping file the following
|
||||
persistence unit metadata:
|
||||
----
|
||||
<persistence-unit-metadata>
|
||||
<xml-mapping-metadata-complete/>
|
||||
</persistence-unit-metadata>
|
||||
----
|
||||
====
|
||||
|
||||
== Canonical Metamodel
|
||||
|
||||
The structure of the metamodel classes is described in the Jakarta Persistence
|
||||
(JSR 317) https://jcp.org/en/jsr/detail?id=317[specification], but for
|
||||
completeness the definition is repeated in the following paragraphs.
|
||||
Feel free to skip ahead to the <<chapter-usage,usage chapter>>, if you
|
||||
are not interested into the gory details.
|
||||
|
||||
The annotation processor produces for every managed entity in the
|
||||
persistence unit a metamodel class based on these rules:
|
||||
|
||||
* For each managed class X in package p, a metamodel class X_ in
|
||||
package p is created.
|
||||
|
||||
* The name of the metamodel class is derived from the name of the
|
||||
managed class by appending "_" to the name of the managed class.
|
||||
|
||||
* The metamodel class X_ must be annotated with the
|
||||
`jakarta.persistence.StaticMetamodel` annotation.
|
||||
|
||||
* If class X extends another class S, where S is the most derived
|
||||
managed class (i.e., entity or mapped superclass) extended by X, then
|
||||
class X_ must extend class S_, where S_ is the metamodel class created
|
||||
for S.
|
||||
|
||||
* For every persistent non-collection-valued attribute y declared by
|
||||
class X, where the type of y is Y, the metamodel class must contain a
|
||||
declaration as follows:
|
||||
|
||||
public static volatile SingularAttribute<X, Y> y;
|
||||
|
||||
* For every persistent collection-valued attribute z declared by class
|
||||
X, where the element type of z is Z, the metamodel class must contain
|
||||
a declaration as follows:
|
||||
** if the collection type of z is java.util.Collection, then
|
||||
|
||||
public static volatile CollectionAttribute<X, Z> z;
|
||||
|
||||
** if the collection type of z is java.util.Set, then
|
||||
|
||||
public static volatile SetAttribute<X, Z> z;
|
||||
|
||||
** if the collection type of z is java.util.List, then
|
||||
|
||||
public static volatile ListAttribute<X, Z> z;
|
||||
|
||||
** if the collection type of z is java.util.Map, then
|
||||
+
|
||||
public static volatile MapAttribute<X, K, Z> z;
|
||||
+
|
||||
where K is the type of the key of the map in class X
|
||||
|
||||
Import statements must be included for the needed `jakarta.persistence.metamodel` types as
|
||||
appropriate and all classes X, Y, Z, and K.
|
||||
|
||||
[[chapter-usage]]
|
||||
== Usage
|
||||
|
||||
The jar file for the annotation processor can be found in the
|
||||
https://search.maven.org/[Maven Central repository] under:
|
||||
|
||||
====
|
||||
[source, XML]
|
||||
[subs="verbatim,attributes"]
|
||||
----
|
||||
<dependency>
|
||||
<groupId>org.hibernate</groupId>
|
||||
<artifactId>hibernate-jpamodelgen</artifactId>
|
||||
<version>{version}</version>
|
||||
</dependency>
|
||||
----
|
||||
====
|
||||
|
||||
Alternatively, it can be found in the ORM distribution bundle on
|
||||
https://sourceforge.net/projects/hibernate/files/hibernate-orm/[SourceForge].
|
||||
|
||||
In most cases the annotation processor will automatically run provided
|
||||
the processor jar is added to the build classpath.
|
||||
This happens due to Java's Service Provider contract and the fact
|
||||
the Hibernate Static Metamodel Generator jar files contains the
|
||||
file _javax.annotation.processing.Processor_ in the _META-INF/services_ directory.
|
||||
|
||||
The fully qualified name of the processor itself is:
|
||||
`org.hibernate.jpamodelgen.JPAMetaModelEntityProcessor`.
|
||||
|
||||
=== Usage from the command line
|
||||
|
||||
[[usage-ant]]
|
||||
==== Usage with Ant
|
||||
|
||||
As mentioned above, the annotation processor will run automatically
|
||||
each time the Java compiler is called, provided the jar file is on the
|
||||
classpath.
|
||||
Sometimes, however, it is useful to control the annotation
|
||||
processing in more detail, for example if you exclusively want to run
|
||||
the processor without compiling any other source files.
|
||||
The <<javac-task-example,Javac task>> configuration below shows how
|
||||
Ant can be configured to just run annotation processing.
|
||||
|
||||
[[javac-task-example]]
|
||||
.Javac Task configuration
|
||||
====
|
||||
[source, XML]
|
||||
----
|
||||
<javac srcdir="${src.dir}"
|
||||
destdir="${target.dir}"
|
||||
failonerror="false"
|
||||
fork="true"
|
||||
classpath="${classpath}">
|
||||
<compilerarg value="-proc:only"/>
|
||||
</javac>
|
||||
----
|
||||
|
||||
====
|
||||
The option _-proc:only_ instructs the compiler to just run the annotation processing.
|
||||
You can also completely disable processing by specifying _-proc:none_.
|
||||
|
||||
[TIP]
|
||||
====
|
||||
Run `'javac -help'` to see which other annotation processor relevant
|
||||
options can be specified.
|
||||
====
|
||||
|
||||
==== Usage with Maven
|
||||
|
||||
There are several ways of running the annotation processor as part of a Maven build.
|
||||
Again, it will automatically run if you are compiling with a JDK >6.
|
||||
In case you have more than one annotation processor on your classpath you can explicitly
|
||||
pass the processor option to the compiler plugin:
|
||||
|
||||
.Maven compiler plugin configuration - direct execution
|
||||
|
||||
====
|
||||
[source, XML]
|
||||
----
|
||||
<plugin>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<configuration>
|
||||
<source>1.8</source>
|
||||
<target>1.8</target>
|
||||
<compilerArguments>
|
||||
<processor>org.hibernate.jpamodelgen.JPAMetaModelEntityProcessor</processor>
|
||||
</compilerArguments>
|
||||
</configuration>
|
||||
</plugin>
|
||||
----
|
||||
|
||||
====
|
||||
The maven-compiler-plugin approach has the disadvantage that the maven compiler plugin
|
||||
does currently not allow to specify multiple compiler arguments
|
||||
(https://jira.codehaus.org/browse/MCOMPILER-62[MCOMPILER-62])
|
||||
and that messages from the Messenger API are suppressed
|
||||
(https://jira.codehaus.org/browse/MCOMPILER-66[MCOMPILER-66]).
|
||||
A better approach is to disable annotation processing for the compiler
|
||||
plugin as seen in below.
|
||||
|
||||
[[disable-processing-maven-compiler-plugin]]
|
||||
.Maven compiler plugin configuration - indirect execution
|
||||
|
||||
====
|
||||
[source, XML]
|
||||
----
|
||||
<plugin>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<configuration>
|
||||
<source>1.8</source>
|
||||
<target>1.8</target>
|
||||
<compilerArgument>-proc:none</compilerArgument>
|
||||
</configuration>
|
||||
</plugin>
|
||||
----
|
||||
====
|
||||
Once disabled, the https://bsorrentino.github.io/maven-annotation-plugin/[maven-processor-plugin]
|
||||
for annotation processing can be used:
|
||||
|
||||
[[maven-processor-plugin]]
|
||||
.Configuration with maven-processor-plugin
|
||||
====
|
||||
[source, XML]
|
||||
[subs="verbatim,attributes"]
|
||||
----
|
||||
<plugin>
|
||||
<groupId>org.bsc.maven</groupId>
|
||||
<artifactId>maven-processor-plugin</artifactId>
|
||||
<version>2.0.5</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>process</id>
|
||||
<goals>
|
||||
<goal>process</goal>
|
||||
</goals>
|
||||
<phase>generate-sources</phase>
|
||||
<configuration>
|
||||
<processors>
|
||||
<processor>org.hibernate.jpamodelgen.JPAMetaModelEntityProcessor</processor>
|
||||
</processors>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.hibernate</groupId>
|
||||
<artifactId>hibernate-jpamodelgen</artifactId>
|
||||
<version>{version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</plugin>
|
||||
----
|
||||
====
|
||||
|
||||
Another possibility is to supply the dependency as an annotation processor path to the maven-compiler-plugin:
|
||||
|
||||
[[maven-compiler-plugin]]
|
||||
.Configuration with maven-compiler-plugin
|
||||
====
|
||||
[source, XML]
|
||||
[subs="verbatim,attributes"]
|
||||
----
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<version>3.7.0</version>
|
||||
<configuration>
|
||||
<annotationProcessorPaths>
|
||||
<path>
|
||||
<groupId>org.hibernate</groupId>
|
||||
<artifactId>hibernate-jpamodelgen</artifactId>
|
||||
<version>{fullVersion}</version>
|
||||
</path>
|
||||
</annotationProcessorPaths>
|
||||
</configuration>
|
||||
</plugin>
|
||||
----
|
||||
====
|
||||
|
||||
=== Usage within the IDE
|
||||
|
||||
Of course you also want to have annotation processing available in your favorite IDE. The
|
||||
following paragraphs and screenshots show you how to enable the Hibernate Static Metamodel
|
||||
Generator within your IDE.
|
||||
|
||||
==== Idea
|
||||
|
||||
Intellij Idea contains from version 9.x onwards a specific configuration section for
|
||||
annotation processing under the project settings window.
|
||||
The screenshots show you how to configure the Hibernate Static Metamodel Generator.
|
||||
|
||||
image:idea-annotation-processor-config.png[]
|
||||
|
||||
In the annotation processor configuration, enable annotation processing and select obtain
|
||||
from project classpath.
|
||||
Add the annotation processor name `org.hibernate.jpamodelgen.JPAMetaModelEntityProcessor`
|
||||
(and optionally the annotation processor options).
|
||||
Select the module(s) containing your entities.
|
||||
If you have configured Maven as recommended, it is best to select the same output directory
|
||||
for the generated classes.
|
||||
At the time of writing, it is _target/generated-sources/apt_. That way, the generated
|
||||
classes will be available in IntelliJ Idea.
|
||||
|
||||
==== Eclipse
|
||||
|
||||
In Eclipse exists also an additional configuration section under Java Compiler.
|
||||
There you can configure all kinds of aspects of annotation processing.
|
||||
Just check the "Enable annotation processing" option, configure the directory for the
|
||||
generated sources and finally add the Hibernate Static Metamodel Generator and Jakarta Persistence jar
|
||||
files to the factory path.
|
||||
|
||||
image:eclipse-annotation-processor-config.png[]
|
||||
|
||||
=== Processor specific options
|
||||
|
||||
The Hibernate Static Metamodel Generator accepts a series of custom
|
||||
options which can be passed to the processor in the format: `-A[property]=[value]`
|
||||
|
||||
The supported properties can be found in the table below:
|
||||
|
||||
.Hibernate Static Metamodel Generator options
|
||||
|===============
|
||||
|*Option name* | *Option value and usage*
|
||||
|
||||
|debug | If set to `true` additional trace
|
||||
information will be outputted by the processor
|
||||
|
||||
|persistenceXml | Per default the processor looks in
|
||||
_/META-INF_ for persistence.xml. Specifying
|
||||
this option a _persitence.xml_ file from a
|
||||
different location can be specified
|
||||
(has to be on the classpath)
|
||||
|
||||
|ormXml | Allows to specify additional entity mapping
|
||||
files. The specified value for this option is a
|
||||
comma separated string of mapping file names.
|
||||
Even when this option is specified
|
||||
_/META-INF/orm.xml_ is implicit.
|
||||
|
||||
|lazyXmlParsing | Possible values are `true` or `false`. If set to
|
||||
`true` the annotation processor tries to
|
||||
determine whether any of the xml files has
|
||||
changed between
|
||||
invocations and if unchanged skips the xml parsing.
|
||||
This feature is experimental and contains the risk
|
||||
of wrong results in some cases of mixed mode
|
||||
configurations. To determine wether a file has
|
||||
been modified a temporary file
|
||||
`Hibernate-Static-Metamodel-Generator.tmp`
|
||||
is used. This file gets created in the
|
||||
`java.io.tmpdir` directory.
|
||||
|
||||
|fullyAnnotationConfigured | If set to `true` the processor will
|
||||
ignore `orm.xml` and `persistence.xml`.
|
||||
|
||||
|addGeneratedAnnotation | If set to `true` the processor will
|
||||
add the @Generated to the generated
|
||||
Java source file. Adding this annotation using
|
||||
JDK 5 will cause a compilation error. In this
|
||||
case set the flag to false. The default for this option is `true`
|
||||
|
||||
|addGenerationDate | If set to true the generation date
|
||||
of the metamodel class will be inserted in the
|
||||
date parameter of the @Generated annotation.
|
||||
The default is `false`. This parameter is
|
||||
ignored if _addGeneratedAnnotation_ is set
|
||||
to _false_.
|
||||
|addSuppressWarningsAnnotation| If set to `true` the processor will
|
||||
add `@SuppressWarnings("all")` to the
|
||||
generated Java source file. Per default this
|
||||
annotation is not generated. See also https://hibernate.onjira.com/browse/METAGEN-50[METAGEN-50].
|
||||
|
||||
|===============
|
||||
|
||||
|
|
@ -1,132 +0,0 @@
|
|||
[[custom-sf-session-guide]]
|
||||
= Custom SessionFactory and Session Implementations Guide
|
||||
:toc:
|
||||
|
||||
The two main contracts of Hibernate, `org.hibernate.SessionFactory` and `org.hibernate.Session`, are both
|
||||
defined as interfaces which allows for custom implementations to be provided. There are two high-level ways
|
||||
in which custom implementations can be provided to users. The first is to develop a custom bootstrap API
|
||||
specific to the custom implementation. The second way is to integrate with the Hibernate bootstrap API.
|
||||
This guide will cover the second approach.
|
||||
|
||||
|
||||
== Implementor contracts
|
||||
|
||||
A Hibernate naming convention is that SPI contracts extending API contracts are named with Implementor appended
|
||||
to the API contract name. For `SessionFactory` and `Session` that is `SessionFactoryImplementor` and
|
||||
`SessionImplementor` respectively. These SPI contracts extra information and functionality needed by internal
|
||||
components as well as other SPI components. Therefore, custom `SessionFactory` and `Session` should additionally
|
||||
implement `org.hibernate.engine.spi.SessionFactoryImplementor` and `org.hibernate.engine.spi.SessionImplementor`.
|
||||
See all pertinent JavaDocs for discussions of implementation details.
|
||||
|
||||
|
||||
== Integration hooks
|
||||
|
||||
`org.hibernate.boot.SessionFactoryBuilder` is part of the Hibernate native bootstrap API where we want to configure
|
||||
the `SessionFactory` to be built. Third parties can hook into this process by supplying a
|
||||
`org.hibernate.boot.spi.SessionFactoryBuilderFactory` via the Java ServiceLoader mechanism (see JavaDocs for
|
||||
`java.util.ServiceLoader` if you are unfamiliar with this service discovery mechanism). As you might guess from their
|
||||
names, a `SessionFactoryBuilderFactory` is responsible for creating `SessionFactoryBuilder` instances and a
|
||||
`SessionFactoryBuilder` is in turn responsible for creating `SessionFactory` instances.
|
||||
|
||||
`org.hibernate.boot.spi.SessionFactoryOptions` are the options ultimately passed to the `SessionFactory` being
|
||||
built. They represent the choices applied by the user via the `SessionFactoryBuilder` contract. Custom integrations
|
||||
can leverage this and the `SessionFactoryBuilder` to also expose custom option setting.
|
||||
|
||||
|
||||
[[example1]]
|
||||
.Custom SessionFactoryBuilderFactory with additional option
|
||||
====
|
||||
[source, JAVA]
|
||||
----
|
||||
public class CustomSessionFactoryBuilderFactory
|
||||
implements SessionFactoryBuilderFactory {
|
||||
@Override
|
||||
public SessionFactoryBuilder getSessionFactoryBuilder(
|
||||
MetadataImplementor metadata,
|
||||
SessionFactoryBuilderImplementor defaultBuilder) {
|
||||
return new CustomSessionFactoryBuilder( metadata, defaultBuilder );
|
||||
}
|
||||
}
|
||||
|
||||
public class CustomSessionFactoryBuilder
|
||||
extends AbstractDelegatingSessionFactoryBuilder {
|
||||
private final MetadataImplementor metadata;
|
||||
|
||||
private final boolean customSetting;
|
||||
|
||||
public DelegatingSessionFactoryBuilder(
|
||||
MetadataImplementor metadata,
|
||||
SessionFactoryBuilderImplementor delegate) {
|
||||
super( delegate );
|
||||
this.metadata = metadata;
|
||||
|
||||
// initialize customSetting, maybe based on config settings...
|
||||
ConfigurationService cfgService = metadata.getMetadataBuildingOptions()
|
||||
.getServiceRegistry()
|
||||
.getService( ConfigurationService.class );
|
||||
this.customSetting = cfgService.getSetting(
|
||||
"com.acme.domain.custom_setting",
|
||||
StandardConverters.BOOLEAN,
|
||||
true
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public DelegatingSessionFactoryBuilder unwrap() {
|
||||
return (DelegatingSessionFactoryBuilder) this;
|
||||
}
|
||||
|
||||
public CustomSessionFactoryBuilder applyCustomSetting(boolean enabled) {
|
||||
this.customSetting = enabled;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SessionFactory build() {
|
||||
CustomSessionFactoryOptions options = new CustomSessionFactoryOptions(
|
||||
getDelegate().buildSessionFactoryOptions(),
|
||||
customSetting
|
||||
);
|
||||
return new CustomSessionFactory( metadata, options );
|
||||
}
|
||||
}
|
||||
|
||||
public class CustomSessionFactoryOptions
|
||||
extends AbstractDelegatingSessionFactoryOptions {
|
||||
private final boolean customSetting;
|
||||
|
||||
public CustomSessionFactoryOptions(
|
||||
SessionFactoryOptions baseOptions,
|
||||
boolean customSetting) {
|
||||
super( baseOptions );
|
||||
this.customSetting = customSetting;
|
||||
}
|
||||
|
||||
public boolean getCustomSetting() {
|
||||
return customSetting;
|
||||
}
|
||||
}
|
||||
----
|
||||
====
|
||||
|
||||
Users can then build your custom `SessionFactory` still using the normal Hibernate bootstrap. In fact,
|
||||
accepting defaults for your custom settings/options, their code does not even change. Of course they
|
||||
can also apply selections to your custom settings/options as well:
|
||||
|
||||
|
||||
|
||||
[[example2]]
|
||||
.Example usage
|
||||
====
|
||||
[source, JAVA]
|
||||
----
|
||||
Metadata metadata = ...;
|
||||
|
||||
// The SessionFactory returned here is concretely
|
||||
// a CustomSessionFactory
|
||||
SessionFactory sf = metadata.getSessionFactoryBuilder()
|
||||
.unwrap( CustomSessionFactoryBuilder.class )
|
||||
.applyCustomSetting( false )
|
||||
.buildSessionFactory();
|
||||
----
|
||||
====
|
|
@ -1,18 +0,0 @@
|
|||
[[wildfly-guide]]
|
||||
= Using latest Hibernate ORM within WildFly
|
||||
|
||||
== Hibernate ORM within WildFly
|
||||
|
||||
The https://wildfly.org/[WildFly application server] includes Hibernate ORM as the default Jakarta Persistence provider out of the box.
|
||||
|
||||
In previous versions of Hibernate ORM, we offered a "feature pack" to enable anyone to use the very latest version in
|
||||
WildFly as soon as a new release of Hibernate ORM was published.
|
||||
|
||||
Unfortunately, since version 5.5 is upgrading to Jakarta Persistence 3.0 and targets integration with components of the Jakarta
|
||||
EE 9 stack, such feature had to be disabled.
|
||||
|
||||
As soon as WildFly releases a Jakarta EE 9 compatible server it might be possible to re-introduce such a feature, but
|
||||
we can't guarantee that we will do this as the server changed the tooling to define such packs.
|
||||
|
||||
As usual, please let us know how important this is for you, and while we'll gladly help to make this happen we might need
|
||||
to rely on volunteers to help by contributing patches, testing it out and providing feedback.
|
|
@ -62,7 +62,8 @@ It was done here only for completeness of an example.
|
|||
|
||||
The `Person_.name` reference is an example of the static form of Jakarta Persistence Metamodel reference.
|
||||
We will use that form exclusively in this chapter.
|
||||
See the documentation for the https://docs.jboss.org/hibernate/orm/{majorMinorVersion}/topical/html_single/metamodelgen/MetamodelGenerator.html[Hibernate Jakarta Persistence Metamodel Generator] for additional details on the Jakarta Persistence static Metamodel.
|
||||
|
||||
See <<tooling>> for details on generating this static metamodel.
|
||||
====
|
||||
|
||||
[[criteria-typedquery-expression]]
|
||||
|
|
|
@ -1,90 +1,25 @@
|
|||
[[tooling]]
|
||||
== Build Tool Integration
|
||||
:rootProjectDir: ../../../../../../..
|
||||
:documentationProjectDir: {rootProjectDir}/documentation
|
||||
:documentationModel: {documentationProjectDir}/src/main/java/org/hibernate/userguide/model
|
||||
|
||||
Hibernate provides a few build-time services available as plugins for
|
||||
https://gradle.org[Gradle], https://maven.org[Maven] and https://ant.org[Ant].
|
||||
Hibernate provides build-time services available as plugins for
|
||||
|
||||
These services include -
|
||||
* <<tooling-gradle,Gradle>>
|
||||
* <<tooling-maven,Maven>>
|
||||
* <<tooling-ant,Ant>>
|
||||
|
||||
* Bytecode enhancement
|
||||
* Schema management
|
||||
* Static Metamodel generation
|
||||
These services include
|
||||
|
||||
* <<tooling-enhancement,Bytecode enhancement>>
|
||||
* <<tooling-modelgen,Static Metamodel generation>>
|
||||
* <<tooling-schema,Schema management>>
|
||||
|
||||
[[tooling-enhancement]]
|
||||
=== Bytecode Enhancement
|
||||
include::enhancement.adoc[]
|
||||
include::modelgen.adoc[]
|
||||
include::schema.adoc[]
|
||||
|
||||
Hibernate performs bytecode enhancement through its `org.hibernate.bytecode.enhance.spi.Enhancer`
|
||||
contract. These build time tools provide a way to incorporate configuration and execution of
|
||||
the enhancer into a build.
|
||||
|
||||
See <<BytecodeEnhancement>> for discussion of the capabilities of an enhanced model.
|
||||
|
||||
[NOTE]
|
||||
====
|
||||
At the moment, only annotated classes are supported for enhancement.
|
||||
====
|
||||
|
||||
|
||||
[[tooling-enhancement-runtime]]
|
||||
==== Runtime Bytecode Enhancement
|
||||
|
||||
Hibernate can also perform run-time bytecode enhancement when used in Jakarta EE compliant
|
||||
containers through `jakarta.persistence.spi.ClassTransformer`. See the documentation of
|
||||
your container for any additional details. Run-time enhancement is controlled through
|
||||
3 true/false settings (all of which default to false):
|
||||
|
||||
`hibernate.enhancer.enableDirtyTracking`:: Whether to enhance the model for dirty-tracking
|
||||
`hibernate.enhancer.enableLazyInitialization`:: Whether to enhance the model for lazy loading at the attribute level. This allows
|
||||
even basic types to be fetched lazily. It also allows definition of fetch groups (`LazyGroup`).
|
||||
`hibernate.enhancer.enableAssociationManagement`:: Whether to automatically synchronize a bidirectional association when only one side is changed.
|
||||
|
||||
|
||||
|
||||
[[tooling-schema]]
|
||||
=== Schema Management
|
||||
|
||||
|
||||
[[tooling-modelgen]]
|
||||
=== Static Metamodel Generation
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
[[tooling-gradle]]
|
||||
=== Gradle Plugin
|
||||
|
||||
For integrating with Gradle, Hibernate provides the
|
||||
https://plugins.gradle.org/plugin/org.hibernate.orm[org.hibernate.orm] plugin which
|
||||
supports bytecode enhancement and static metamodel generation but not schema tooling.
|
||||
|
||||
[source,gradle]
|
||||
----
|
||||
include::extras/gradle-example.gradle[]
|
||||
----
|
||||
|
||||
|
||||
[[tooling-maven]]
|
||||
=== Maven Plugin
|
||||
|
||||
Hibernate provides a Maven plugin capable of providing build-time enhancement of the domain
|
||||
model as they are compiled as part of a Maven build. See the section on the
|
||||
<<BytecodeEnhancement-enhancement-gradle>> for details on the configuration settings. Again, the default for those 3 is `false`.
|
||||
|
||||
The Maven plugin supports one additional configuration settings: failOnError, which controls what happens in case of error.
|
||||
The default behavior is to fail the build, but it can be set so that only a warning is issued.
|
||||
|
||||
.Apply the Maven plugin
|
||||
====
|
||||
[source,xml]
|
||||
----
|
||||
include::extras/maven-example.pom[]
|
||||
----
|
||||
====
|
||||
|
||||
|
||||
[[tooling-ant]]
|
||||
=== Ant Plugin
|
||||
|
||||
todo - https://hibernate.atlassian.net/browse/HHH-15171
|
||||
include::gradle.adoc[]
|
||||
include::maven.adoc[]
|
||||
include::ant.adoc[]
|
||||
|
|
|
@ -0,0 +1,36 @@
|
|||
[[tooling-ant]]
|
||||
=== Ant Plugin
|
||||
|
||||
Hibernate provides https://ant.apache.org/[Ant] support ...
|
||||
|
||||
|
||||
[[tooling-ant-modelgen]]
|
||||
==== Static Metamodel Generation in Ant
|
||||
|
||||
As mentioned in <<tooling-modelgen>>, the generator is implemented as an
|
||||
annotation processor and can be used anywhere javac is used - such as
|
||||
Ant's https://ant.apache.org/manual/Tasks/javac.html[javac] task.
|
||||
|
||||
[[javac-task-example]]
|
||||
.Javac task configuration
|
||||
====
|
||||
[source, XML]
|
||||
----
|
||||
<javac srcdir="${src.dir}"
|
||||
destdir="${target.dir}"
|
||||
failonerror="false"
|
||||
fork="true"
|
||||
classpath="${classpath}">
|
||||
<compilerarg value="-processorpath" />
|
||||
<compilerarg value="/path/to/metamodel-generator.jar"/>
|
||||
<compilerarg value="-proc:only"/>
|
||||
</javac>
|
||||
----
|
||||
|
||||
====
|
||||
|
||||
|
||||
[[tooling-ant-schema]]
|
||||
==== Schema Management
|
||||
|
||||
Coming soon
|
|
@ -0,0 +1,27 @@
|
|||
[[tooling-enhancement]]
|
||||
=== Bytecode Enhancement
|
||||
|
||||
Hibernate performs bytecode enhancement through its `org.hibernate.bytecode.enhance.spi.Enhancer`
|
||||
contract. These build time tools provide a way to incorporate configuration and execution of
|
||||
the enhancer into a build.
|
||||
|
||||
See <<BytecodeEnhancement>> for discussion of the capabilities of an enhanced model.
|
||||
|
||||
[NOTE]
|
||||
====
|
||||
At the moment, only annotated classes are supported for enhancement.
|
||||
====
|
||||
|
||||
|
||||
[[tooling-enhancement-runtime]]
|
||||
==== Runtime Bytecode Enhancement
|
||||
|
||||
Hibernate can also perform run-time bytecode enhancement when used in Jakarta EE compliant
|
||||
containers through `jakarta.persistence.spi.ClassTransformer`. See the documentation of
|
||||
your container for any additional details. Run-time enhancement is controlled through
|
||||
3 true/false settings (all of which default to false):
|
||||
|
||||
`hibernate.enhancer.enableDirtyTracking`:: Whether to enhance the model for dirty-tracking
|
||||
`hibernate.enhancer.enableLazyInitialization`:: Whether to enhance the model for lazy loading at the attribute level. This allows
|
||||
even basic types to be fetched lazily. It also allows definition of fetch groups (`LazyGroup`).
|
||||
`hibernate.enhancer.enableAssociationManagement`:: Whether to automatically synchronize a bidirectional association when only one side is changed.
|
|
@ -1,23 +0,0 @@
|
|||
plugins {
|
||||
// e.g., let's use the 6.0.0.Final version of the plugin
|
||||
id "org.hibernate.orm" version "6.0.0.Final"
|
||||
}
|
||||
|
||||
hibernate {
|
||||
enhancement {
|
||||
// all default to false
|
||||
lazyInitialization true
|
||||
dirtyTracking true
|
||||
associationManagement true
|
||||
}
|
||||
jpaMetamodel {
|
||||
// defaults to true
|
||||
applyGeneratedAnnotation true
|
||||
// defaults to ['raw', 'deprecation']
|
||||
suppress 'raw'
|
||||
// defaults to `${buildDir}/generated/sources/jpaMetamodel
|
||||
generationOutputDirectory "${buildDir}/generated/sources/modelgen"
|
||||
// defaults to `${buildDir}/classes/java/jpaMetamodel
|
||||
compileOutputDirectory "${buildDir}/classes/java/modelgen"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,113 @@
|
|||
[[tooling-gradle]]
|
||||
=== Gradle Plugin
|
||||
|
||||
For integrating with https://gradle.org[Gradle], Hibernate provides the
|
||||
https://plugins.gradle.org/plugin/org.hibernate.orm[org.hibernate.orm] plugin which
|
||||
supports bytecode enhancement and static metamodel generation but not schema tooling.
|
||||
|
||||
To apply the plugin, use Gradle's `plugins {}` block:
|
||||
|
||||
[source,gradle]
|
||||
----
|
||||
plugins {
|
||||
id "org.hibernate.orm" version "<version-to-use>"
|
||||
}
|
||||
----
|
||||
|
||||
|
||||
Applying the plugin creates a `hibernate` extension (`HibernateOrmSpec`) to configure the plugin.
|
||||
By default, when the plugin is applied, support for both bytecode enhancement and static metamodel
|
||||
generation is enabled.
|
||||
|
||||
[source,gradle]
|
||||
----
|
||||
hibernate {
|
||||
// for illustration, let's disable both
|
||||
disableEnhancement
|
||||
disableJpaMetamodel
|
||||
}
|
||||
----
|
||||
|
||||
[[tooling-gradle-enhancement]]
|
||||
==== Bytecode Enhancement
|
||||
|
||||
Enhancement is configured through the `enhancement` extension:
|
||||
|
||||
[source,gradle]
|
||||
----
|
||||
hibernate {
|
||||
enhancement {
|
||||
// for illustration, enable them all
|
||||
lazyInitialization true
|
||||
dirtyTracking true
|
||||
associationManagement true
|
||||
}
|
||||
}
|
||||
----
|
||||
|
||||
The extension is of type `EnhancementSpec` which exposes the following properties:
|
||||
|
||||
|
||||
enableLazyInitialization:: Whether to incorporate lazy loading support into the enhanced bytecode
|
||||
enableDirtyTracking:: Whether to incorporate dirty tracking into the enhanced bytecode
|
||||
enableAssociationManagement:: Whether to add bidirectional association management into the enhanced bytecode
|
||||
|
||||
|
||||
Which all default to false (disabled).
|
||||
|
||||
It also exposes the following method forms:
|
||||
|
||||
* lazyInitialization(boolean)
|
||||
* dirtyTracking(boolean)
|
||||
* associationManagement(boolean)
|
||||
|
||||
|
||||
[[tooling-gradle-modelgen]]
|
||||
==== Static Metamodel Generation
|
||||
|
||||
One approach to integrate Static Metamodel generation into a Gradle build is to
|
||||
use Gradle's support for annotation processors -
|
||||
|
||||
[source,gradle]
|
||||
----
|
||||
dependencies {
|
||||
annotationProcessor "org.hibernate.orm:hibernate-jpamodelgen:${hibernateVersion}"
|
||||
}
|
||||
----
|
||||
|
||||
When the build does not need bytecode enhancement support, this is a perfectly valid solution.
|
||||
|
||||
The plugin supports simpler configuration of the generator using the registered
|
||||
`jpaMetamodel` extension:
|
||||
|
||||
|
||||
[source,gradle]
|
||||
----
|
||||
hibernate {
|
||||
jpaMetamodel {
|
||||
applyGeneratedAnnotation false
|
||||
suppress 'raw'
|
||||
generationOutputDirectory "${buildDir}/generated/sources/modelgen"
|
||||
compileOutputDirectory "${buildDir}/classes/java/modelgen"
|
||||
}
|
||||
}
|
||||
----
|
||||
|
||||
The extension is of type `JpaMetamodelGenerationSpec`, which exposes the following configuration properties:
|
||||
|
||||
applyGeneratedAnnotation:: Should the `javax.annotation.processing.Generated` annotation be added to the
|
||||
generated classes. Defaults to `true`.
|
||||
suppressions:: Suppressions to add to the generated classes. Defaults to `['raw', 'deprecation']`
|
||||
generationOutputDirectory:: Directory where the generated metamodel classes should be created. Defaults
|
||||
to `${buildDir}/generated/sources/jpaMetamodel`
|
||||
[[tooling-gradle-modelgen-compile-output]]
|
||||
compileOutputDirectory:: Directory where the classes compiled from the generated metamodel classes should be
|
||||
created. Defaults to `${buildDir}/classes/java/jpaMetamodel`.
|
||||
|
||||
It also exposes the following method forms:
|
||||
|
||||
* applyGeneratedAnnotation(boolean)
|
||||
* suppress(String)
|
||||
* generationOutputDirectory(Object)
|
||||
* compileOutputDirectory(Object)
|
||||
|
Before Width: | Height: | Size: 173 KiB After Width: | Height: | Size: 173 KiB |
Before Width: | Height: | Size: 365 KiB After Width: | Height: | Size: 365 KiB |
|
@ -0,0 +1,16 @@
|
|||
[[tooling-maven]]
|
||||
=== Maven Plugin
|
||||
|
||||
Hibernate provides a https://maven.apache.org/[Maven] plugin capable of providing
|
||||
build-time enhancement of the domain model as they are compiled as part of a Maven
|
||||
build. See the section on the <<tooling-gradle>> for details
|
||||
on the configuration settings. By default, all enhancements are disabled.
|
||||
|
||||
|
||||
.Apply the Maven plugin
|
||||
====
|
||||
[source,xml]
|
||||
----
|
||||
include::extras/maven-example.pom[]
|
||||
----
|
||||
====
|
|
@ -0,0 +1,109 @@
|
|||
[[tooling-modelgen]]
|
||||
=== Static Metamodel Generator
|
||||
:rootProjectDir: ../../../../../../..
|
||||
:documentationProjectDir: {rootProjectDir}/documentation
|
||||
:documentationModel: {documentationProjectDir}/src/main/java/org/hibernate/userguide/model
|
||||
:documentationMetamodel: {documentationProjectDir}/target/generated/sources/annotationProcessor/java/main/org/hibernate/userguide/model
|
||||
:toolingTestsDir: {documentationProjectDir}/src/test/java/org/hibernate/userguide/tooling
|
||||
|
||||
Jakarta Persistence defines a typesafe Criteria API which allows `Criteria` queries to be constructed in a
|
||||
strongly-typed manner, utilizing so-called static metamodel classes. For developers, it is important that
|
||||
the task of the metamodel generation can be automated. Hibernate Static Metamodel Generator is an annotation
|
||||
processor based on https://jcp.org/en/jsr/detail?id=269[JSR_269] with the task of creating Jakarta Persistence
|
||||
static metamodel classes.
|
||||
|
||||
See <<criteria>> for discussion of Jakarta Persistence criteria queries.
|
||||
|
||||
The Hibernate Static Metamodel Generator is defined by the published `org.hibernate.orm:metamodel-generator`
|
||||
artifact. As it is defined as an
|
||||
https://docs.oracle.com/en/java/javase/11/tools/javac.html#GUID-082C33A5-CBCA-471A-845E-E77F79B7B049[annotation processor],
|
||||
it is usable anytime `javac` is used. See the tool-specific discussions (<<tooling-gradle,Gradle>>, <<tooling-maven,Maven>>
|
||||
and <<tooling-ant,Ant>>) for details on integrating the generator into those environments.
|
||||
|
||||
NOTE:: The fully qualified name of the processor class is `org.hibernate.jpamodelgen.JPAMetaModelEntityProcessor`.
|
||||
|
||||
[TIP]
|
||||
====
|
||||
The `javac` option _-proc:only_ instructs the compiler to just run the annotation processing.
|
||||
You can also disable annotation processing by specifying _-proc:none_.
|
||||
|
||||
Run `'javac -help'` to see which other annotation processor relevant options can be specified.
|
||||
====
|
||||
|
||||
|
||||
The structure of the metamodel classes is described in the Jakarta Persistence
|
||||
specification, but for completeness the definition is repeated in the following
|
||||
paragraphs. For every class in a persistence-unit, the generator will produce
|
||||
a static metamodel class based on the following rules:
|
||||
|
||||
* For each managed class `X` in package `p`, a metamodel class `X_` is created in package `p`.
|
||||
* The name of the metamodel class is derived from the name of the managed class by appending "_" to the managed class name.
|
||||
* The metamodel class `X_` must be annotated with the `jakarta.persistence.StaticMetamodel` annotation. The generation
|
||||
can also be configured to add the `javax.annotation.processing.Generated` annotation.
|
||||
* If class `X` extends another class `S`, where `S` is the most derived managed class extended by `X`, then
|
||||
class `X_` must extend class `S_`, where `S_` is the metamodel class created for `S`.
|
||||
* For every persistent singular attribute `y` declared by class `X`, where the type of `y` is `Y`,
|
||||
the metamodel class must contain a declaration as follows:
|
||||
|
||||
public static volatile SingularAttribute<X, Y> y;
|
||||
|
||||
* For every persistent plural attribute `z` declared by class `X`, where the element type of `z` is `Z`, the metamodel
|
||||
class must contain a declaration as follows:
|
||||
|
||||
** if the collection type of `z` is `java.util.Collection`, then
|
||||
|
||||
public static volatile CollectionAttribute<X, Z> z;
|
||||
|
||||
** if the collection type of `z` is `java.util.Set`, then
|
||||
|
||||
public static volatile SetAttribute<X, Z> z;
|
||||
|
||||
** if the collection type of `z` is `java.util.List`, then
|
||||
|
||||
public static volatile ListAttribute<X, Z> z;
|
||||
|
||||
** if the collection type of `z` is `java.util.Map`, then
|
||||
+
|
||||
public static volatile MapAttribute<X, K, Z> z;
|
||||
+
|
||||
where `K` is the type of the key of the map in class `X`
|
||||
|
||||
* Import statements must be included for `jakarta.persistence.metamodel` types as
|
||||
needed, as well as all domain model classes (i.e., `X`, `S`, `Y`, `Z`, and `K`).
|
||||
|
||||
As an example, consider the following domain model -
|
||||
|
||||
[[ex-tooling-modelgen-model]]
|
||||
.`Order` and `Item` entities
|
||||
====
|
||||
[source, JAVA, indent=0]
|
||||
----
|
||||
include::{documentationModel}/tooling/Customer.java[tags=tooling-modelgen-model]
|
||||
include::{documentationModel}/tooling/Order.java[tags=tooling-modelgen-model]
|
||||
include::{documentationModel}/tooling/Item.java[tags=tooling-modelgen-model]
|
||||
----
|
||||
====
|
||||
|
||||
Given this model, the generator will produce classes named `Customer_`, `Order_` and `Item_`. As an example:
|
||||
|
||||
[[tooling-modelgen-metamodel]]
|
||||
.`Order_`
|
||||
====
|
||||
[source, JAVA, indent=0]
|
||||
----
|
||||
include::{documentationMetamodel}/tooling/Order_.java[]
|
||||
----
|
||||
====
|
||||
|
||||
At boot-time, Hibernate will find these classes and populate them. They can then be used in
|
||||
Criteria queries for type-safe path references. For example:
|
||||
|
||||
[[tooling-modelgen-usage]]
|
||||
.Static Metamodel usage
|
||||
====
|
||||
[source, JAVA, indent=0]
|
||||
----
|
||||
include::{toolingTestsDir}/modelgen/ModelGenTests.java[tags=tooling-modelgen-usage]
|
||||
----
|
||||
====
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
[[tooling-schema]]
|
||||
=== Schema Management
|
||||
|
||||
Coming soon
|
|
@ -0,0 +1,39 @@
|
|||
/*
|
||||
* 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
|
||||
*/
|
||||
package org.hibernate.userguide.model.tooling;
|
||||
|
||||
import jakarta.persistence.Entity;
|
||||
import jakarta.persistence.Table;
|
||||
import jakarta.persistence.Id;
|
||||
import jakarta.persistence.Basic;
|
||||
|
||||
/**
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
@Table(name = "customers")
|
||||
//tag::tooling-modelgen-model[]
|
||||
@Entity
|
||||
public class Customer {
|
||||
@Id
|
||||
private Integer id;
|
||||
@Basic
|
||||
private String name;
|
||||
|
||||
// getters and setters omitted for brevity
|
||||
//end::tooling-modelgen-model[]
|
||||
|
||||
private Customer() {
|
||||
// for Hibernate use
|
||||
}
|
||||
|
||||
public Customer(Integer id, String name) {
|
||||
this.id = id;
|
||||
this.name = name;
|
||||
}
|
||||
//tag::tooling-modelgen-model[]
|
||||
}
|
||||
//end::tooling-modelgen-model[]
|
|
@ -0,0 +1,45 @@
|
|||
/*
|
||||
* 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
|
||||
*/
|
||||
package org.hibernate.userguide.model.tooling;
|
||||
|
||||
import jakarta.persistence.Entity;
|
||||
import jakarta.persistence.Id;
|
||||
import jakarta.persistence.ManyToOne;
|
||||
import jakarta.persistence.Table;
|
||||
|
||||
/**
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
@Table(name = "items")
|
||||
//tag::tooling-modelgen-model[]
|
||||
@Entity
|
||||
public class Item {
|
||||
@Id
|
||||
Integer id;
|
||||
|
||||
int quantity;
|
||||
|
||||
@ManyToOne
|
||||
Order order;
|
||||
|
||||
// getters and setters omitted for brevity
|
||||
//end::tooling-modelgen-model[]
|
||||
|
||||
public Item() {
|
||||
}
|
||||
|
||||
public Item(Integer id, int quantity, Order order) {
|
||||
this.id = id;
|
||||
this.quantity = quantity;
|
||||
this.order = order;
|
||||
|
||||
order.items.add( this );
|
||||
}
|
||||
|
||||
//tag::tooling-modelgen-model[]
|
||||
}
|
||||
//end::tooling-modelgen-model[]
|
|
@ -0,0 +1,49 @@
|
|||
/*
|
||||
* 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
|
||||
*/
|
||||
package org.hibernate.userguide.model.tooling;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.Set;
|
||||
import jakarta.persistence.Entity;
|
||||
import jakarta.persistence.Id;
|
||||
import jakarta.persistence.ManyToOne;
|
||||
import jakarta.persistence.OneToMany;
|
||||
import jakarta.persistence.Table;
|
||||
|
||||
/**
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
//tag::tooling-modelgen-model[]
|
||||
@Entity
|
||||
@Table(name = "orders")
|
||||
public class Order {
|
||||
@Id
|
||||
Integer id;
|
||||
|
||||
@ManyToOne
|
||||
Customer customer;
|
||||
|
||||
@OneToMany
|
||||
Set<Item> items;
|
||||
BigDecimal totalCost;
|
||||
|
||||
// standard setter/getter methods
|
||||
|
||||
//end::tooling-modelgen-model[]
|
||||
|
||||
public Order() {
|
||||
}
|
||||
|
||||
public Order(Integer id, Customer customer, BigDecimal totalCost) {
|
||||
this.id = id;
|
||||
this.customer = customer;
|
||||
this.totalCost = totalCost;
|
||||
}
|
||||
//tag::tooling-modelgen-model[]
|
||||
}
|
||||
//end::tooling-modelgen-model[]
|
||||
|
|
@ -0,0 +1,44 @@
|
|||
/*
|
||||
* 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
|
||||
*/
|
||||
package org.hibernate.userguide.tooling.modelgen;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import jakarta.persistence.criteria.CriteriaBuilder;
|
||||
import jakarta.persistence.criteria.CriteriaQuery;
|
||||
import jakarta.persistence.criteria.Root;
|
||||
|
||||
import org.hibernate.userguide.model.tooling.Customer;
|
||||
import org.hibernate.userguide.model.tooling.Item;
|
||||
import org.hibernate.userguide.model.tooling.Order;
|
||||
import org.hibernate.userguide.model.tooling.Order_;
|
||||
|
||||
import org.hibernate.testing.orm.junit.DomainModel;
|
||||
import org.hibernate.testing.orm.junit.SessionFactory;
|
||||
import org.hibernate.testing.orm.junit.SessionFactoryScope;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
/**
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
@DomainModel( annotatedClasses = { Order.class, Item.class, Customer.class } )
|
||||
@SessionFactory
|
||||
public class ModelGenTests {
|
||||
@Test
|
||||
public void testIt(SessionFactoryScope scope) {
|
||||
scope.inTransaction( (session) -> {
|
||||
//tag::tooling-modelgen-usage[]
|
||||
final CriteriaBuilder criteriaBuilder = session.getCriteriaBuilder();
|
||||
final CriteriaQuery<Customer> criteria = criteriaBuilder.createQuery( Customer.class );
|
||||
|
||||
final Root<Order> root = criteria.from( Order.class );
|
||||
|
||||
criteria.select( root.get( Order_.customer ) );
|
||||
criteria.where( criteriaBuilder.greaterThan( root.get( Order_.totalCost ), new BigDecimal( 100 ) ) );
|
||||
//end::tooling-modelgen-usage[]
|
||||
} );
|
||||
}
|
||||
}
|
|
@ -77,6 +77,10 @@ public class JpaMetamodelGenerationSpec {
|
|||
return applyGeneratedAnnotation;
|
||||
}
|
||||
|
||||
public void applyGeneratedAnnotation(boolean apply) {
|
||||
applyGeneratedAnnotation.set( apply );
|
||||
}
|
||||
|
||||
public SetProperty<String> getSuppressions() {
|
||||
return suppressions;
|
||||
}
|
||||
|
|
|
@ -300,6 +300,7 @@ public class JpaMetamodelGenerationTask extends DefaultTask {
|
|||
public static void apply(HibernateOrmSpec ormDsl, SourceSet mainSourceSet, Project project) {
|
||||
final String mainCompileTaskName = mainSourceSet.getCompileJavaTaskName();
|
||||
final JavaCompile mainCompileTask = (JavaCompile) project.getTasks().getByName( mainCompileTaskName );
|
||||
final Task compileResourcesTask = project.getTasks().getByName( "processResources" );
|
||||
|
||||
final JpaMetamodelGenerationTask genTask = project.getTasks().create(
|
||||
DSL_NAME,
|
||||
|
@ -313,8 +314,6 @@ public class JpaMetamodelGenerationTask extends DefaultTask {
|
|||
genTask.setDescription( "Generates the JPA 'static metamodel'" );
|
||||
|
||||
genTask.dependsOn( mainCompileTask );
|
||||
|
||||
final Task compileResourcesTask = project.getTasks().getByName( "processResources" );
|
||||
genTask.dependsOn( compileResourcesTask );
|
||||
|
||||
final JavaCompile compileJpaMetamodelTask = project.getTasks().create( COMPILE_DSL_NAME, JavaCompile.class );
|
||||
|
@ -323,6 +322,7 @@ public class JpaMetamodelGenerationTask extends DefaultTask {
|
|||
compileJpaMetamodelTask.setSourceCompatibility( mainCompileTask.getSourceCompatibility() );
|
||||
compileJpaMetamodelTask.setTargetCompatibility( mainCompileTask.getTargetCompatibility() );
|
||||
genTask.finalizedBy( compileJpaMetamodelTask );
|
||||
mainCompileTask.finalizedBy( compileJpaMetamodelTask );
|
||||
compileJpaMetamodelTask.dependsOn( genTask );
|
||||
compileJpaMetamodelTask.source( project.files( ormDsl.getJpaMetamodelSpec().getGenerationOutputDirectory() ) );
|
||||
compileJpaMetamodelTask.getDestinationDirectory().set( ormDsl.getJpaMetamodelSpec().getCompileOutputDirectory() );
|
||||
|
|
Loading…
Reference in New Issue