Skip to content

Commit

Permalink
Improved Criteria docs (#3136)
Browse files Browse the repository at this point in the history
* Improved Criteria docs

* Use different mssql docker image since the default one is failing

* Missed one more place where MSSQL is used

---------

Co-authored-by: radovanradic <[email protected]>
  • Loading branch information
dstepanov and radovanradic authored Sep 19, 2024
1 parent 792e8a0 commit ad578b1
Show file tree
Hide file tree
Showing 17 changed files with 93 additions and 92 deletions.
15 changes: 0 additions & 15 deletions data-connection-jdbc/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -21,33 +21,18 @@ dependencies {

testImplementation mnReactor.micronaut.reactor

testImplementation(mnTestResources.testcontainers.mysql)
testImplementation(mnTestResources.testcontainers.mariadb)
testImplementation(mnTestResources.testcontainers.postgres)
testImplementation(mnTestResources.testcontainers.mssql)
testImplementation(mnTestResources.testcontainers.oracle.xe)

testCompileOnly mn.micronaut.inject.groovy

testImplementation mn.micronaut.http.netty
testRuntimeOnly mnSql.micronaut.jdbc.tomcat
testRuntimeOnly mnSql.h2
testRuntimeOnly mnSql.mariadb.java.client
testRuntimeOnly mnSql.ojdbc11
testRuntimeOnly mnSql.mysql.connector.java
testRuntimeOnly mnSql.postgresql
testRuntimeOnly mnSql.mssql.jdbc
testRuntimeOnly mn.snakeyaml

testResourcesService mnSql.mariadb.java.client
testResourcesService mnSql.ojdbc11
testResourcesService mnSql.mysql.connector.java
testResourcesService mnSql.postgresql
testResourcesService mnSql.mssql.jdbc

testImplementation libs.micronaut.testresources.client

testRuntimeOnly mnSerde.micronaut.serde.oracle.jdbc.json
}

micronaut {
Expand Down
1 change: 1 addition & 0 deletions data-jdbc/src/test/resources/application.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ test-resources:
mssql:
accept-license: true
startup-timeout: 300s
image-name: mcr.microsoft.com/mssql/server:2022-latest
mariadb:
startup-timeout: 300s
mysql:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
*/
package io.micronaut.data.repository.jpa.criteria;

import io.micronaut.core.annotation.Internal;
import io.micronaut.core.annotation.NonNull;
import io.micronaut.core.annotation.Nullable;
import jakarta.persistence.criteria.CriteriaBuilder;
Expand All @@ -37,7 +38,8 @@
* @author Denis Stepanov
* @since 3.2
*/
class SpecificationComposition {
@Internal
final class SpecificationComposition {

@NonNull
static <T> QuerySpecification<T> composed(@Nullable QuerySpecification<T> lhs, @Nullable QuerySpecification<T> rhs, Combiner combiner) {
Expand Down
1 change: 1 addition & 0 deletions data-r2dbc/src/test/resources/application.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ test-resources:
mssql:
accept-license: true
startup-timeout: 300s
image-name: mcr.microsoft.com/mssql/server:2022-latest
mariadb:
startup-timeout: 300s
mysql:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@ class SqlServerHibernateTransactionSpec extends HibernateTransactionSpec impleme
"datasources.default.name" : "mymssqldb",
'jpa.default.properties.hibernate.hbm2ddl.auto' : 'create-drop',
'jpa.default.properties.hibernate.dialect' : 'org.hibernate.dialect.SQLServerDialect',
'test-resources.containers.mssql.accept-license' : 'true'
'test-resources.containers.mssql.accept-license' : 'true',
'test-resources.containers.mssql.image-name' : 'mcr.microsoft.com/mssql/server:2022-latest'
]
}

Expand Down
16 changes: 5 additions & 11 deletions src/main/docs/guide/dbc/dbcCriteriaSpecifications.adoc
Original file line number Diff line number Diff line change
@@ -1,20 +1,14 @@
In some cases, you need to build a query programmatically and at the runtime; for that, Micronaut Data implements a subset of Jakarta Persistence Criteria API 3.0, which can be used for Micronaut Data JDBC and R2DBC features. To utilize this feature add the following dependency:
Micronaut Criteria API for JDBC / R2DBC currently implements only a subset of the API.

dependency:jakarta.persistence:jakarta.persistence-api[]

To implement queries that cannot be defined at the compile-time Micronaut Data introduces api:data.repository.JpaSpecificationExecutor[] repository interface that can be used to extend your repository interface:

snippet::example.PersonRepository[project-base="doc-examples/jdbc-example",source="main" tags="repository",indent="0"]
To use Jakarta Criteria API you need to add an optional dependency:

Each method expects a "specification" which is a functional interface with a set of Criteria API objects intended to build a query programmatically.

Micronaut Criteria API currently implements only a subset of the API. Most of it is internally used to create queries with predicates and projections.
dependency:jakarta.persistence:jakarta.persistence-api[]

Currently, not supported JPA Criteria API features:

- Joins with custom `ON` expressions and typed join methods like `joinSet` etc
- Joins with custom `ON` expressions
- Operators dealing with an entity type and casting
- Collection operations: `isMember` etc
- Tuple result type
- Transformation expressions like toString, substring etc.
- Cases
Expand Down

This file was deleted.

25 changes: 0 additions & 25 deletions src/main/docs/guide/hibernate/hibernateSpecifications.adoc

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -6,19 +6,19 @@ Micronaut Data includes different variations of specification executor interface
|*Interface*
|*Description*

|api:data.repository.JpaSpecificationExecutor[]
|api:data.repository.jpa.JpaSpecificationExecutor[]
|The default interface for querying, deleting and updating data

|api:data.repository.async.AsyncJpaSpecificationExecutor[]
|api:data.repository.jpa.async.AsyncJpaSpecificationExecutor[]
|The async version of the specifications repository

|api:data.repository.reactive.ReactiveStreamsJpaSpecificationExecutor[]
|api:data.repository.jpa.reactive.ReactiveStreamsJpaSpecificationExecutor[]
|The reactive streams - `Publisher<>` version of the specifications repository

|api:data.repository.reactive.ReactorJpaSpecificationExecutor[]
|api:data.repository.jpa.reactive.ReactorJpaSpecificationExecutor[]
|The Reactor version of the specifications repository

|api:data.repository.kotlin.CoroutineJpaSpecificationExecutor[]
|api:data.repository.jpa.kotlin.CoroutineJpaSpecificationExecutor[]
|The Kotlin version of the interface that is using coroutines

|===
|===
1 change: 1 addition & 0 deletions src/main/docs/guide/shared.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,4 @@ The following sections describe shared concepts of all Micronaut Data modules:
- <<querying, Querying>> - define a repository method to access your data
- <<dataUpdates, Data access>> - data access operations
- <<transactions, Transactions>> - transactional access support
- <<criteriaSpecifications, Jakarta Criteria API>> - using criteria to write queries
7 changes: 7 additions & 0 deletions src/main/docs/guide/shared/criteriaSpecifications.adoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
In some cases, you need to build a query programmatically and at the runtime; for that, Micronaut Data supports Jakarta Persistence Criteria API 3.0.

To implement queries that cannot be defined at the compile-time Micronaut Data introduces api:data.repository.JpaSpecificationExecutor[] repository interface that can be used to extend your repository interface:

snippet::example.PersonRepository[project-base="doc-examples/jdbc-example",source="main" tags="repository",indent="0"]

Each method expects a "specification" which is a functional interface with a set of Criteria API objects intended to build a query programmatically.
Original file line number Diff line number Diff line change
Expand Up @@ -65,3 +65,7 @@ snippet::example.PersonRepositorySpec[project-base="doc-examples/jdbc-example",s
NOTE: The examples use compile-known values, and in this case, it would be better to create custom repository methods which would come with compile-time generates queries and eliminate runtime overhead.
It's recommended to use criteria only for dynamic queries where the query structure is not known at the build-time.

Pagination with JOINS cannot be properly implemented with limiting the results for tabular SQL results, because of that Micronaut Data will execute two queries:

- 1. Fetching a page of entity IDs
- 2. Fetching a complete entity with JOINed associations
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
Micronaut Data includes different variations of specification executor interface intended to be used with async or reactive repositories.

.Builtin Variations of `JpaSpecificationExecutor` repository interface
[cols=2*]
|===
|*Interface*
|*Description*

|api:data.repository.jpa.JpaSpecificationExecutor[]
|The default interface for querying, deleting and updating data

|api:data.repository.jpa.async.AsyncJpaSpecificationExecutor[]
|The async version of the specifications repository

|api:data.repository.jpa.reactive.ReactiveStreamsJpaSpecificationExecutor[]
|The reactive streams - `Publisher<>` version of the specifications repository

|api:data.repository.jpa.reactive.ReactorJpaSpecificationExecutor[]
|The Reactor version of the specifications repository

|api:data.repository.jpa.kotlin.CoroutineJpaSpecificationExecutor[]
|The Kotlin version of the interface that is using coroutines

|===

.Each variation supports different Criteria specifications
[cols=2*]
|===
|*Interface*
|*Description*

|api:data.repository.jpa.criteria.PredicateSpecification[]
|A simple interface that is producing `Predicate` using the `Root` and `CriteriaBuilder`

|api:data.repository.jpa.criteria.QuerySpecification[]
|The same as `PredicateSpecification` which also includes `CriteriaQuery`

|api:data.repository.jpa.criteria.DeleteSpecification[]
|The same as `PredicateSpecification` which also includes `CriteriaDelete`

|api:data.repository.jpa.criteria.UpdateSpecification[]
|The same as `PredicateSpecification` which also includes `CriteriaUpdate`

|api:data.repository.jpa.criteria.CriteriaQueryBuilder[]
|The builder of `CriteriaQuery` using `CriteriaBuilder`

|api:data.repository.jpa.criteria.CriteriaUpdateBuilder[]
|The builder of `CriteriaUpdate` using `CriteriaBuilder`

|api:data.repository.jpa.criteria.CriteriaDeleteBuilder[]
|The builder of `CriteriaDelete` using `CriteriaBuilder`

|===
Original file line number Diff line number Diff line change
Expand Up @@ -15,15 +15,15 @@ q.select(customer.get(Customer_.name))
.where(cb.equal(item.get(Item_.product).get(Product_.productType), "printer"));
----

Note that as of this writing you cannot use Micronaut Data annotations (those found in the io.micronaut.data.annotation package) to generate static JPA metadata, the only supported way is to use Jakarta Persistence annotations (located in the `jakarta.persistence` package) in combination with Hibernate JPA Static Metamodel Generator which will generate the metamodel even if at runtime you do not actually use Hibernate, but instead use Micronaut Data JDBC.

To configure the metamodel generator simply add the following dependency to the annotation processor classpath:

dependency:hibernate-jpamodelgen[groupId="org.hibernate.orm", scope="annotationProcessor"]

NOTE: The Hibernate 6 version of `hibernate-jpamodelgen-jakarta` is required because prior versions of Hibernate are still using the `javax.persistence` package.
For Kotlin, add the dependency in https://docs.micronaut.io/4.4.3/guide/#kaptOrKsp[kapt or ksp scope], and for Groovy add it in compileOnly scope.

NOTE: The generator supports only Jakarta Persistence annotation (located in the `jakarta.persistence` package), it's not possible to use Micronaut Data annotations (those found in the io.micronaut.data.annotation package) to generate static JPA metadata.

And we need to include the generated classes on the Java classpath to have them accessible:

Example for Gradle builds:
Expand Down
15 changes: 8 additions & 7 deletions src/main/docs/guide/toc.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
introduction:
title: Introduction
repository: Repository
repository: Repository
whatsNew: What's New?
breaks: Breaking Changes
releaseHistory: Release History
Expand Down Expand Up @@ -31,6 +31,13 @@ shared:
deletes: Deleting
timestamps: Entity Timestamps
entityEvents: Entity Events
criteriaSpecifications:
title: Repositories with Jakarta Criteria API
criteriaExecuteQuery: Querying
criteriaExecuteUpdate: Updating
criteriaExecuteDelete: Deleting
otherRepositoryVariations: Different repository variations
typeSafeJava: Type-Safe Java queries
transactions:
title: Transactions
programmaticTransactions: Programmatic Transactions
Expand All @@ -51,7 +58,6 @@ hibernate:
hibernateExplicitQueries: Explicit queries
hibernateNativeQueries: Native queries
hibernateProcedures: Procedures
hibernateSpecifications: JPA specifications
hibernateReactive: Micronaut Data Hibernate Reactive
dbc:
title: Micronaut Data JDBC and R2DBC
Expand All @@ -73,11 +79,6 @@ dbc:
pessimisticLocking: Pessimistic Locking
dbcCriteriaSpecifications:
title: Repositories with Criteria API
criteriaExecuteQuery: Querying
criteriaExecuteUpdate: Updating
criteriaExecuteDelete: Deleting
otherRepositoryVariations: Other repository variations
typeSafeJava: Type-Safe Java queries
sqlMapping:
title: Mapping Entities
sqlAnnotations: SQL Annotations
Expand Down

0 comments on commit ad578b1

Please sign in to comment.