No ano passado, escrevi dois artigos sobre JPA Criteria e Querydsl (veja os artigos Introdução e Metamodelo). Desde o final do ano passado, houve um novo lançamento importante do Spring Boot 3. Este lançamento é baseado no Spring Framework 6 com várias mudanças significativas e questões que devemos considerar ao atualizar.
O objetivo deste artigo é destacar essas mudanças ao atualizar o projeto sat-jpa (projeto SAT). As tecnologias utilizadas aqui são:
- Spring Boot 3.0.2,
- Hibernate 6.1.6.Final
- Spring Data JPA 3.0.1 e
- Querydsl 5.0.0.
Spring Framework 6.0.4
O Spring Framework 6 tem muitas mudanças (veja O que há de novo no Spring Framework 6.x), as principais mudanças são:
- Mudar a base do Java para Java 17 (ainda a última versão LTS do Java na época de escrever este artigo) — ou seja, é a versão mínima do Java que temos que usar.
- Mudar a base do Jakarta para Jakarta EE 9+.
Além disso, há apenas uma pequena mudança no Spring MVC usado no projeto SAT.
Spring MVC 6.0.4
Todos os métodos na classe ResponseEntityExceptionHandler
mudaram suas assinaturas. O argumento status
foi alterado do tipo HttpStatus
para HttpStatusCode
(veja a mudança na classe CityExceptionHandler).
HttpStatus no Spring MVC 5
@Override
protected ResponseEntity<Object> handleMethodArgumentNotValid(MethodArgumentNotValidException exception,
HttpHeaders headers, HttpStatus status, WebRequest request) {
return buildResponse(BAD_REQUEST, exception);
}
HttpStatusCode no Spring MVC 6
@Override
protected ResponseEntity<Object> handleMethodArgumentNotValid(MethodArgumentNotValidException exception,
HttpHeaders headers, HttpStatusCode status, WebRequest request) {
return buildResponse(BAD_REQUEST, exception);
}
Spring Boot 3.0.2
O Spring Boot 3 apresenta diversas mudanças (veja Notas de Lançamento do Spring Boot 3.0); as mais importantes são estas:
- Java 17 (definido pelo Spring Framework).
-
Atualização para o Spring Framework 6 (veja acima).
-
Atualize para Hibernate 6 (veja abaixo).
- Migração das dependências JavaEE para Jakarta EE — isso não é importante em nosso caso, pois não dependemos do Java empresarial aqui, mas pode afetar muitas dependências (por exemplo, API de servlet, validação, persistência, JMS, etc.).
- Pequena mudança no Spring MVC 6 na classe
ResponseEntityExceptionHandler
(veja a próxima parte).
Vamos começar com as mudanças simples de Jakarta EE. Assim, podemos nos concentrar na persistência depois disso.
Dependências de Jakarta EE
A mudança significativa é a migração das dependências Java EE para Jakarta EE. O Spring Framework 6 estabeleceu a linha de base como Jakarta EE 9 (veja O que há de novo no Spring Framework 6.x), mas o Spring Boot 3 já usa Jakarta EE 10 (veja Notas de Lançamento do Spring Boot 3.0) para muitas APIs (por exemplo, Servlet ou JPA — para citar algumas tecnologias).
Como consequência, todas as classes que utilizam outra classe do pacote jakarta
precisam mudar para a mesma classe do pacote javax
(veja, por exemplo, anotações como PostConstruct ou Entity).
Importações Javax
import javax.annotation.PostConstruct;
import javax.persistence.Entity;
Importações Jakarta
import jakarta.annotation.PostConstruct;
import jakarta.persistence.Entity;
Hibernate 6.1.6
Outra mudança importante no Spring Boot 3 é a atualização de Hibernate 5.6 para Hibernate 6.1. Os detalhes sobre o Hibernate 6.1 podem ser encontrados aqui ou nos notas de lançamento.
Sinceramente, não prestei atenção a essa mudança até ter que corrigir um teste falhando devido a um tamanho de resultado diferente (veja a correção no classe CountryRepositoryCustomTests
). A implementação com o novo Hibernate 6 retorna menos entidades do que antes.
Vale a pena mencionar duas mudanças aqui com base nessa investigação. Vamos começar com o registro em log.
Registro
Os registradores do Hibernate foram alterados de org.hibernate.type
para org.hibernate.orm.jdbc
(veja esta referência e esta referência).
Nota: todos os itens de configuração disponíveis podem ser encontrados no classe org.hibernate.cfg.AvailableSettings
.
Hibernate 5
Havia um único logger para os valores ocultos e extraídos.
logging.level.org.hibernate.type.descriptor.sql.BasicBinder=TRACE
Hibernate 6
O Hibernate 6 alterou o pacote principal e dividiu-os em dois registradores diferentes para distinguir a operação -> quais valores devem ser registrados.
logging.level.org.hibernate.orm.jdbc.bind=trace
logging.level.org.hibernate.orm.jdbc.extract=trace
Modelo de Consulta Semântica
Com o registro corrigido, foi confirmado que o Hibernate realmente extrai duas informações do DB:
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]
No entanto, o teste recebe apenas uma entidade do Hibernate, como você pode ver nessas capturas de tela de depuração:
O comportamento alterado é causado pelo novo Modelo de Consulta Semântica com Deduplicação Automática (veja a parte Modelo de Consulta Semântica) introduzido com o Hibernate 6 (veja a linha 178 na classe org.hibernate.sql.results.spi.ListResultsConsumer
). O Hibernate 6 agora retorna o resultado deduplicado.
Gerador JPA do Hibernate
A dependência Maven Hibernate Jpamodelgen gerenciada por Spring Boot Dependencies foi movida do pacote org.hibernate
para org.hibernate.orm
. Veja:
Spring Boot 2.7.5
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-jpamodelgen</artifactId>
</dependency>
Spring Boot 3.0.2
<dependency>
<groupId>org.hibernate.orm</groupId>
<artifactId>hibernate-jpamodelgen</artifactId>
</dependency>
Liquibase
Para concluir as dependências de persistência básica, o Liquibase foi atualizado de versão 4.9.1 para 4.17.2. Não há diferença significativa, exceto pelo uso da dependência JAX-B. A dependência deve usar JAX-B da Jakarta em vez de Javax (veja o seguinte referência).
Spring Boot 2.7.5
<dependency>
<groupId>org.liquibase</groupId>
<artifactId>liquibase-core</artifactId>
</dependency>
Spring Boot 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>
Spring Data JPA 3.0.1
O Spring Boot 3.0.2 depende do Spring Data Release Train 2022.0.1 (veja Spring Data 2022.0 – Notas de Lançamento de Turing), onde o Spring Data JPA 3.0.1 é usado com essas mudanças chave (veja as notas de lançamento):
- Mudar a base do Java para Java 17,
- Mudar a base da Jakarta para Jakarta EE 10 e
- Aumentar para o Hibernate 6
Nota: a versão anteriormente utilizada (no nosso caso) era a versão 2.7.5.
Querydsl 5.0.0
A versão do Querydsl não foi alterada, mas foi impactada de maneira semelhante à do Liquibase. As dependências precisam ser usadas da Jakarta em vez da Javax. Portanto, a dependência do Querydsl precisa usar a classificação jakarta
em vez da antiga classificação jpa
(veja este referência).
Spring Boot 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>
Spring Boot 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>
Conclusão
Este artigo cobriu a atualização para o mais recente Spring Boot 3.0.2 para JPA e Querydsl (no momento de escrever este artigo). O artigo começou com as mudanças no Spring Framework e Spring Boot. Em seguida, todas as alterações no Hibernate e tecnologias relacionadas foram abordadas. No final, mencionamos as pequenas mudanças relacionadas a Spring Data 3.0.1 e Querydsl 5.0.0.
O código-fonte completo demonstrado acima está disponível no meu GitHub repositório.
Nota: também há um artigo anterior, Upgrade Guide To Spring Data Elasticsearch 5.0, dedicado a uma atualização semelhante do Elasticsearch com o Spring Boot 3.
Source:
https://dzone.com/articles/upgrade-guide-to-spring-boot-3-for-spring-data-jpa-3-and-querydsl-5