L’année dernière, j’ai écrit deux articles sur JPA Criteria et Querydsl (voir les articles Introduction et Metamodel). Depuis la fin de l’année dernière, il y a eu une nouvelle version majeure de Spring Boot 3. Cette version est basée sur Spring Framework 6 avec plusieurs modifications et problèmes importants que nous devons prendre en compte lors de la mise à niveau.
Le but de cet article est de mettre en évidence ces changements lors de la mise à jour du projet sat-jpa (projet SAT). Les technologies utilisées ici sont :
- Démarrage de printemps 3.0.2,
- Hibernation 6.1.6.Final
- Spring Data JPA 3.0.1 et
- Querydsl 5.0.0.
Cadre de printemps 6.0.4
Spring Framework 6 a de nombreux changements (voir Quoi de neuf dans Spring Framework 6.x), les principaux changements sont :
- Basculez la ligne de base de Java vers Java 17 (toujours le dernier Java LTS au moment de la rédaction de cet article) – c’est-à-dire qu’il s’agit d’une version minimale de Java que nous devons utiliser.
- Basculez la ligne de base de Jakarta vers Jakarta EE 9+.
En plus de cela, il n’y a qu’un seul changement mineur dans Spring MVC utilisé dans le projet SAT.
Printemps MVC 6.0.4
Toutes les méthodes du ResponseEntityExceptionHandler
classe ont changé leurs signatures. Le status
l’argument a été changé de HttpStatus
pour HttpStatusCode
type (voir le changement dans la classe CityExceptionHandler).
HttpStatus dans Spring MVC 5
@Override
protected ResponseEntity<Object> handleMethodArgumentNotValid(MethodArgumentNotValidException exception,
HttpHeaders headers, HttpStatus status, WebRequest request) {
return buildResponse(BAD_REQUEST, exception);
}
HttpStatusCode dans Spring MVC 6
@Override
protected ResponseEntity<Object> handleMethodArgumentNotValid(MethodArgumentNotValidException exception,
HttpHeaders headers, HttpStatusCode status, WebRequest request) {
return buildResponse(BAD_REQUEST, exception);
}
Démarrage de printemps 3.0.2
Spring Boot 3 a de nombreux changements (voir les notes de publication de Spring Boot 3.0); les plus importantes sont celles-ci :
Commençons par les changements simples de Jakarta EE. Nous pouvons donc nous concentrer sur la persévérance après cela.
Dépendances EE de Jakarta
Le changement significatif est la migration des dépendances Java EE vers Jakarta EE. Spring Framework 6 a défini la ligne de base comme Jakarta EE 9 (voir Quoi de neuf dans Spring Framework 6.x), mais Spring Boot 3 utilise déjà Jakarta EE 10 (voir Spring Boot 3.0 Release Notes ) pour de nombreuses API (par exemple, Servlet ou JPA – pour nommer certaines technologies).
Par conséquent, toutes les classes utilisant une autre classe du jakarta
package doit passer à la même classe à partir du javax
package à la place (voir, par exemple, les annotations PostConstruct ou Entity).
Importations Javax
import javax.annotation.PostConstruct;
import javax.persistence.Entity;
Importations de Jakarta
import jakarta.annotation.PostConstruct;
import jakarta.persistence.Entity;
Hibernation 6.1.6
Un autre changement majeur dans Spring Boot 3 est la mise à niveau de Hibernate 5.6 vers Hibernate 6.1. Les détails sur Hibernate 6.1 peuvent être trouvés ici ou dans les notes de version.
Honnêtement, je n’ai pas prêté attention à ce changement jusqu’à ce que je doive corriger un test défaillant en raison d’une taille de résultat différente (voir le correctif dans le CountryRepositoryCustomTests
classe). L’implémentation avec le nouvel Hibernate 6 renvoie moins d’entités qu’auparavant.
Il convient de mentionner ici deux changements basés sur cette enquête. Commençons d’abord par la journalisation.
Enregistrement
Les enregistreurs Hibernate sont passés de org.hibernate.type
pour org.hibernate.orm.jdbc
(voir cette référence et cette référence).
Remarque : tous les éléments de configuration disponibles se trouvent dans org.hibernate.cfg.AvailableSettings
classe.
Hiberner 5
Il y avait un seul enregistreur pour les valeurs bidden et extraites.
logging.level.org.hibernate.type.descriptor.sql.BasicBinder=TRACE
Hibernation 6
Hibernate 6 a modifié le package principal et les a divisés en deux enregistreurs différents afin de distinguer l’opération -> quelle valeur doit être enregistrée.
logging.level.org.hibernate.orm.jdbc.bind=trace
logging.level.org.hibernate.orm.jdbc.extract=trace
Modèle de requête sémantique
Comme la journalisation a été corrigée, il a été confirmé que Hibernate extrait réellement deux enregistrements de la base de données :
2023-01-25T08:40:18.819+01:00 INFO 6192 --- [ main] c.g.a.s.j.c.CountryRepositoryCustomTests : Started CountryRepositoryCustomTests in 4.678 seconds (process running for 5.745)
Hibernate: select c2_0.id,c2_0.name from city c1_0 join country c2_0 on c2_0.id=c1_0.country_id where c1_0.name like ? escape '!' and c1_0.state like ? escape '!'
2023-01-25T08:40:19.221+01:00 TRACE 6192 --- [ main] org.hibernate.orm.jdbc.extract : extracted value ([1] : [BIGINT]) - [3]
2023-01-25T08:40:19.222+01:00 TRACE 6192 --- [ main] org.hibernate.orm.jdbc.extract : extracted value ([2] : [VARCHAR]) - [USA]
2023-01-25T08:40:19.240+01:00 TRACE 6192 --- [ main] org.hibernate.orm.jdbc.extract : extracted value ([1] : [BIGINT]) - [3]
2023-01-25T08:40:19.241+01:00 TRACE 6192 --- [ main] org.hibernate.orm.jdbc.extract : extracted value ([2] : [VARCHAR]) - [USA]
Cependant, le test ne reçoit qu’une seule entité de l’Hibernate, comme vous pouvez le voir dans ces captures d’écran de débogage :
Le changement de comportement est causé par le nouveau Modèle de requête sémantique avec déduplication automatique (voir la partie Semantic Query Model) introduit avec Hibernate 6 (voir ligne 178 dans org.hibernate.sql.results.spi.ListResultsConsumer
classe). Hibernate 6 renvoie maintenant le résultat dédupliqué.
Hiberner JPA Générateur
Le Hiberner Jpamodelgen la dépendance maven gérée par Spring Boot Dependencies a été déplacée de org.hibernate
pour org.hibernate.orm
emballer. Voir:
Démarrage de printemps 2.7.5
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-jpamodelgen</artifactId>
</dependency>
Démarrage de printemps 3.0.2
<dependency>
<groupId>org.hibernate.orm</groupId>
<artifactId>hibernate-jpamodelgen</artifactId>
</dependency>
Liquibase
Pour terminer les dépendances de persistance de base, la Liquibase est mise à niveau de la version 4.9.1 à 4.17.2. Il n’y a pas de différence significative à l’exception de l’utilisation de la dépendance JAX-B. La dépendance doit utiliser JAX-B de Jakarta au lieu de Javax (voir la référence suivante).
Démarrage de printemps 2.7.5
<dependency>
<groupId>org.liquibase</groupId>
<artifactId>liquibase-core</artifactId>
</dependency>
Démarrage de printemps 3.0.2
<dependency>
<groupId>org.liquibase</groupId>
<artifactId>liquibase-core</artifactId>
<exclusions>
<exclusion> <!-- due to SB 3.0 switch to Jakarta -->
<groupId>javax.xml.bind</groupId>
<artifactId>jaxb-api</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>jakarta.xml.bind</groupId>
<artifactId>jakarta.xml.bind-api</artifactId>
</dependency>
Données de printemps JPA 3.0.1
Spring Boot 3.0.2 dépend de Spring Data Release Train 2022.0.1 (voir Spring Data 2022.0 – Turing Release Notes), où Spring Data JPA 3.0.1 est utilisé avec ces changements clés (voir les notes de version) :
- Passer de la ligne de base Java à Java 17,
- Basculez la ligne de base de Jakarta vers Jakarta EE 10 et
- Passez à Hibernate 6
Remarque : la version utilisée précédemment (dans notre cas) était la version 2.7.5.
Querydsl 5.0.0
La version de Querydsl n’a pas été modifiée, mais elle a été impactée de la même manière que la Liquibase. Les dépendances doivent être utilisées depuis Jakarta au lieu de Javax. Par conséquent, la dépendance Querydsl doit utiliser jakarta
classificateur au lieu de l’ancien jpa
classificateur (voir cette référence).
Démarrage de printemps 2.7.5
<dependency>
<groupId>com.querydsl</groupId>
<artifactId>querydsl-jpa</artifactId>
</dependency>
<dependency>
<groupId>com.querydsl</groupId>
<artifactId>querydsl-apt</artifactId>
<version>${querydsl.version}</version>
<classifier>jpa</classifier>
<scope>provided</scope>
</dependency>
Démarrage de printemps 3.0.2
<dependency>
<groupId>com.querydsl</groupId>
<artifactId>querydsl-jpa</artifactId>
<version>${querydsl.version}</version>
<classifier>jakarta</classifier>
</dependency>
<dependency>
<groupId>com.querydsl</groupId>
<artifactId>querydsl-apt</artifactId>
<scope>provided</scope>
<version>${querydsl.version}</version>
<classifier>jakarta</classifier>
</dependency>
Conclusion
Cet article a couvert la mise à niveau vers le dernier Spring Boot 3.0.2 pour JPA et Querydsl (au moment de la rédaction de cet article). L’article a commencé avec les modifications de Spring Framework et Spring Boot. Ensuite, toutes les modifications apportées à Hibernate et aux technologies associées ont été couvertes. Au final, nous avons mentionné les modifications mineures liées à Spring Data 3.0.1 et Querydsl 5.0.0.
Le code source complet présenté ci-dessus est disponible dans mon référentiel GitHub.
Remarque : il existe également un article précédent, Upgrade Guide To Spring Data Elasticsearch 5.0, consacré à une mise à niveau similaire d’Elasticsearch avec Spring Boot 3.