Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion bom/application/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,8 @@
<jakarta.json-api.version>2.1.3</jakarta.json-api.version>
<jakarta.json.bind-api.version>3.0.1</jakarta.json.bind-api.version>
<jakarta.mail-api.version>2.1.3</jakarta.mail-api.version>
<jakarta.persistence-api.version>3.1.0</jakarta.persistence-api.version>
<!--jakarta.persistence-api.version is located in the root pom -->
<jakarta.data-api.version>1.0.1</jakarta.data-api.version>
<jakarta.resource-api.version>2.1.0</jakarta.resource-api.version>
<jakarta.servlet-api.version>6.0.0</jakarta.servlet-api.version>
<jakarta.transaction-api.version>2.0.1</jakarta.transaction-api.version>
Expand Down Expand Up @@ -4390,6 +4391,11 @@
<artifactId>jakarta.persistence-api</artifactId>
<version>${jakarta.persistence-api.version}</version>
</dependency>
<dependency>
<groupId>jakarta.data</groupId>
<artifactId>jakarta.data-api</artifactId>
<version>${jakarta.data-api.version}</version>
</dependency>
<dependency>
<groupId>jakarta.resource</groupId>
<artifactId>jakarta.resource-api</artifactId>
Expand Down
11 changes: 11 additions & 0 deletions docs/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -3230,6 +3230,17 @@
<versionString>${hibernate-validator.version}</versionString>
</configuration>
</execution>
<execution>
<id>parse-version-jakarta-persistence</id>
<goals>
<goal>parse-version</goal>
</goals>
<phase>validate</phase>
<configuration>
<propertyPrefix>jakarta-persistence</propertyPrefix>
<versionString>${jakarta.persistence-api.version}</versionString>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
Expand Down
2 changes: 2 additions & 0 deletions docs/src/main/asciidoc/_attributes.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
:hibernate-orm-version-major-minor: ${hibernate-orm.majorVersion}.${hibernate-orm.minorVersion}
:hibernate-search-version-major-minor: ${hibernate-search.majorVersion}.${hibernate-search.minorVersion}
:hibernate-validator-version-major-minor: ${hibernate-validator.majorVersion}.${hibernate-validator.minorVersion}
:jakarta-persistence-version-major-minor: ${jakarta-persistence.majorVersion}.${jakarta-persistence.minorVersion}
// .
:quarkus-home-url: ${quarkus-home-url}
:quarkus-org-url: https://github.com/quarkusio
Expand All @@ -56,6 +57,7 @@
:hibernate-orm-dialect-docs-url: https://docs.jboss.org/hibernate/orm/{hibernate-orm-version-major-minor}/dialect/dialect.html
:hibernate-search-docs-url: https://docs.jboss.org/hibernate/search/{hibernate-search-version-major-minor}/reference/en-US/html_single/
:hibernate-validator-docs-url: https://docs.jboss.org/hibernate/validator/{hibernate-validator-version-major-minor}/reference/en-US/html_single/
:jakarta-persistence-spec-url: https://jakarta.ee/specifications/persistence/{jakarta-persistence-version-major-minor}/jakarta-persistence-spec-{jakarta-persistence-version-major-minor}#a6072
// .
:amazon-services-guide: https://docs.quarkiverse.io/quarkus-amazon-services/dev/index.html
:config-consul-guide: https://docs.quarkiverse.io/quarkus-config-extensions/dev/consul.html
Expand Down
131 changes: 131 additions & 0 deletions docs/src/main/asciidoc/hibernate-orm.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -1646,3 +1646,134 @@ try {
Since Quarkus has built-in exception mappers for `jakarta.validation.ConstraintViolationException`,
explicitly handling these exceptions might be redundant. See the xref:validation.adoc#rest-end-point-validation[REST end point validation]
section of the Hibernate Validator guide for more details.

[[jakarta-data]]
== Static metamodel and Jakarta Data

Both static metamodel and Jakarta Data capabilities of Hibernate ORM are available in Quarkus
through the `hibernate-jpamodelgen` annotation processor. Since it is an annotation processor,
you must configure the annotation processor in your build tool:

[source,xml,role="primary asciidoc-tabs-target-sync-cli asciidoc-tabs-target-sync-maven"]
.pom.xml
----
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<annotationProcessorPaths>
<path>
<groupId>org.hibernate.orm</groupId>
<artifactId>hibernate-jpamodelgen</artifactId>
<!-- Note, no artifact version is required, it's managed by Quarkus. -->
</path>
<!-- other processors that may be required by your app -->
</annotationProcessorPaths>
<!-- Other compiler plugin configuration options -->
</configuration>
</plugin>
----

[source,gradle,role="secondary asciidoc-tabs-target-sync-gradle"]
.build.gradle
----
// Enforce the version management of your annotation processor dependencies,
// so that there's no need to define an explicit version of the hibernate-jpamodelgen
annotationProcessor enforcedPlatform("${quarkusPlatformGroupId}:${quarkusPlatformArtifactId}:${quarkusPlatformVersion}")
annotationProcessor 'org.hibernate.orm:hibernate-jpamodelgen'
----

=== Static metamodel

The generated static metamodel allows for building queries in a type-safe manner.
Let's consider having a simple entity:

[source,java]
----
@Entity
public class MyEntity {
@Id
@GeneratedValue
public Integer id;

@Column(unique = true)
public String name;
}
----

A query created with the help of static metamodel may look as:

[source,java]
----
var builder = session.getCriteriaBuilder();
var criteria = builder.createQuery(MyEntity.class);
var e = criteria.from(MyEntity_.class);
criteria.where(e.get(MyEntity_.name).equalTo(name));
var query = session.createQuery(criteria);
var result = query.list();
----

For a more detailed overview of static metamodel, please refer to the link:{jakarta-persistence-spec-url}#a6072[Jakarta Persistence specification].

=== Jakarta Data

Jakarta Data requires, besides having the `hibernate-jpamodelgen` annotation processor in place, one extra dependency to be added:

[source,xml,role="primary asciidoc-tabs-target-sync-cli asciidoc-tabs-target-sync-maven"]
.pom.xml
----
<dependency>
<groupId>jakarta.data</groupId>
<artifactId>jakarta.data-api</artifactId>
</dependency>
----

[source,gradle,role="secondary asciidoc-tabs-target-sync-gradle"]
.build.gradle
----
implementation 'jakarta.data:jakarta.data-api'
----

With this dependency, and the annotation processor in place you could simply create your repositories as follows:

[source,java]
----
@Repository
public interface MyRepository extends CrudRepository<MyEntity, Integer> { // <1>

@Query("select e from MyEntity e where e.name like :name") // <2>
List<MyEntity> findByName(String name);

@Delete // <3>
void delete(String name);

}
----
1. To skip the boilerplate definition of CRUD operations,
we can use one of the available interfaces (e.g. `CrudRepository` or `BasicRepository`).
2. Adding custom queries with parameters is as easy as providing your query string to the `@Query` annotation.
3. If the basic CRUD operations from the Jakarta Data interfaces are not enough,
we can always add a custom one, in this case a delete operation that removes `MyEntity`s by name.

And then the repository can be used as any other bean:

[source,java]
----
public class MyEntityResource {

@Inject
MyRepository repository;

@POST
@Transactional
public void create(MyEntity entity) {
repository.insert(entity);
}

// ...

}
----

Please refer to the corresponding https://hibernate.org/repositories/[Hibernate Data Repositories]
and https://jakarta.ee/specifications/data/1.0/jakarta-data-1.0[Jakarta Data]
guides to learn what else they have to offer.
148 changes: 148 additions & 0 deletions integration-tests/hibernate-orm-data/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>quarkus-integration-tests-parent</artifactId>
<groupId>io.quarkus</groupId>
<version>999-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>

<artifactId>quarkus-integration-test-hibernate-orm-data</artifactId>
<name>Quarkus - Integration Tests - Hibernate ORM with Jakarta Data</name>

<dependencies>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-hibernate-orm</artifactId>
</dependency>
<dependency>
<groupId>jakarta.data</groupId>
<artifactId>jakarta.data-api</artifactId>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-rest</artifactId>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-rest-jackson</artifactId>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-jdbc-h2</artifactId>
</dependency>

<!-- test dependencies -->
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-junit5</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-junit5-internal</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.rest-assured</groupId>
<artifactId>rest-assured</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.assertj</groupId>
<artifactId>assertj-core</artifactId>
<scope>test</scope>
</dependency>

<!-- Minimal test dependencies to *-deployment artifacts for consistent build order -->
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-hibernate-orm-deployment</artifactId>
<version>${project.version}</version>
<type>pom</type>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>*</groupId>
<artifactId>*</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-jdbc-h2-deployment</artifactId>
<version>${project.version}</version>
<type>pom</type>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>*</groupId>
<artifactId>*</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-rest-deployment</artifactId>
<version>${project.version}</version>
<type>pom</type>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>*</groupId>
<artifactId>*</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-rest-jackson-deployment</artifactId>
<version>${project.version}</version>
<type>pom</type>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>*</groupId>
<artifactId>*</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>

<build>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
</resource>
</resources>
<plugins>
<plugin>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-maven-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>build</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<annotationProcessorPaths>
<path>
<groupId>org.hibernate.orm</groupId>
<artifactId>hibernate-jpamodelgen</artifactId>
</path>
</annotationProcessorPaths>
</configuration>
</plugin>
</plugins>
</build>


</project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package io.quarkus.it.hibernate.jpamodelgen.data;

import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.Id;

@Entity
public class MyEntity {

@Id
@GeneratedValue
public Integer id;

@Column(unique = true)
public String name;

MyEntity() {
}

public MyEntity(String name) {
this.name = name;
}

@Override
public String toString() {
return "MyOrmEntity [id=" + id + ", name=" + name + "]";
}

}
Loading
Loading