מדריך עדכון ל-Spring Boot 3.0 עבור Spring Data JPA ו-Querydsl

לשנה שעברה, כתבתי שני מאמרים על JPA Criteria ו-Querydsl (ראה מבוא ו-מטמול מאמרים). מאז סוף השנה שעברה, הופיעה שחרור חדש מרכזי של Spring Boot 3. שחרור זה מבוסס על Spring Framework 6 עם מספר שינויים משמעותיים ונושאים שעלינו לשקול כאשר אנו עוברים על השיפורים.

המטרה של מאמר זה היא להדגיש את השינויים האלה כאשר אנו עוברים על הפרויקט sat-jpa (פרויקט SAT). הטכנולוגיות המשמשות כאן הן:

  1. Spring Boot 3.0.2,
  2. Hibernate 6.1.6.Final
  3. Spring Data JPA 3.0.1 ו-
  4. Querydsl 5.0.0.

Spring Framework 6.0.4

Spring Framework 6 כולל שינויים רבים (ראה מה חדש ב-Spring Framework 6.x), השינויים העיקריים הם:

  1. לעבור את בסיס Java ל-Java 17 (עדיין ה-Java LTS האחרון בזמן כתיבת המאמר) – כלומר, זו הגרלת ה-Java המינימלית שעלינו להשתמש.
  2. לעבור את בסיס Jakarta ל-Jakarta EE 9+.

מלבד זאת, יש רק שינוי קלוני אחד ב-Spring MVC המשמש בפרויקט SAT.

Spring MVC 6.0.4

כל השיטות במחלקה ResponseEntityExceptionHandler שינו את חתימותיהן. הארגומנט status שונה מסוג HttpStatus לסוג HttpStatusCode (ראה את השינוי במחלקה CityExceptionHandler).

HttpStatus ב-Spring MVC 5

Java

 

@Override
protected ResponseEntity<Object> handleMethodArgumentNotValid(MethodArgumentNotValidException exception,
		HttpHeaders headers, HttpStatus status, WebRequest request) {
	return buildResponse(BAD_REQUEST, exception);
}

HttpStatusCode ב-Spring MVC 6

Java

 

@Override
protected ResponseEntity<Object> handleMethodArgumentNotValid(MethodArgumentNotValidException exception, 
        HttpHeaders headers, HttpStatusCode status, WebRequest request) {
	return buildResponse(BAD_REQUEST, exception);
}

Spring Boot 3.0.2

Spring Boot 3 כולל שינויים רבים (ראה Spring Boot 3.0 Release Notes); החשובים ביותר הם אלה:

  • Java 17 (מוגדר על ידי ה-Spring Framework).
  • העלאה ל-Spring Framework 6 (ראה לעיל).
  • העלאה ל Hibernate 6 (ראה להלן).
  • העברת תלויות JavaEE ל-Jakarta EE – זה לא חשוב במקרה שלנו מאחר ואנו לא מסתמכים על Java הנפרד כאן, אך זה יכול להשפיע על הרבה תלויות (למשל, API סרוויל, אימות, קיום, JMS וכד').
  • שינוי קטן ב-Spring MVC 6 במחלקה ResponseEntityExceptionHandler (ראה החלק הבא).

בואו נתחיל עם השינויים הפשוטים של Jakarta EE. כך נוכל להתמקד בקיום לאחר מכן.

תלויות Jakarta EE

השינוי המשמעותי הוא ההעברה מתלויות Java EE ל-Jakarta EE. Spring Framework 6 הגדיר את הבסיס כ-Jakarta EE 9 (ראה מה חדש ב-Spring Framework 6.x), אך Spring Boot 3 כבר משתמש ב-Jakarta EE 10 (ראה הערות שחרור Spring Boot 3.0) עבור הרבה APIs (למשל, Servlet או JPA – לשם דוגמה).

כתוצאה מכך, כל המחלקות המשתמשות במחלקה אחרת מחבילת jakarta חייבות לעבור לאותה מחלקה מחבילת javax במקום (ראה, למשל, התיוגים PostConstruct או Entity).

ייבואי Javax

Java

 

import javax.annotation.PostConstruct;
import javax.persistence.Entity;

ייבואי Jakarta

Java

 

import jakarta.annotation.PostConstruct;
import jakarta.persistence.Entity;

Hibernate 6.1.6

שינוי מרכזי נוסף ב-Spring Boot 3 הוא השדרוג מ-Hibernate 5.6 ל-Hibernate 6.1. הפרטים על Hibernate 6.1 ניתן למצוא כאן או בתוך ההערות השחרור.

למען האמת, לא הקשבתי לשינוי זה עד שהייתי צריך לתקן בדיקה נכשלת עקב גודל תוצאה שונה (ראה את התיקון במחלקה CountryRepositoryCustomTests). היישום עם Hibernate 6 החדש מחזיר פחות יחידות מקודם.

שווה לציין שני שינויים כאן על סמך החקירה הזו. בואו נתחיל עם היסטוריית ההתחלה קודם.

רישום

היומנים של Hibernate השתנו מ-org.hibernate.type ל-org.hibernate.orm.jdbc (ראה האזכור הזה ו-האזכור הזה).

הערה: כל האפשרויות המתוקנות הזמינות ניתן למצוא במחלקה org.hibernate.cfg.AvailableSettings.

Hibernate 5

היו יומן אחד לערכים הנסתרים והמוצאים.

Properties files

 

logging.level.org.hibernate.type.descriptor.sql.BasicBinder=TRACE

Hibernate 6

Hibernate 6 שינה את החבילה העיקרית והתפצלה לשני יומנים שונים כדי להבחין בפעולה -> איזה ערך צריך להיות רשום.

Properties files

 

logging.level.org.hibernate.orm.jdbc.bind=trace
logging.level.org.hibernate.orm.jdbc.extract=trace

מודל שאילתא סמנטית

כשהרישום נתקן, נאמת שה-Hibernate באמת מוצא שני רשומות מן ה-DB:

Plain Text

 

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]

עם זאת, המבחן מקבל רק יחידה אחת מה-Hibernate, כפי שאפשר לראות בתצוגות הבאגים הללו:

ההתנהגות השתנתה בגלל המודל החדש מודל שאילתא סמנטית עם הפחתת כפילויות אוטומטית (ראה חלק מודל שאילתא סמנטית) המובא עם Hibernate 6 (ראה שורה 178 במחלקה org.hibernate.sql.results.spi.ListResultsConsumer). כעת Hibernate 6 מחזירת את התוצאה המופחתת.

Hibernate JPA Generator

המממת המייט של Hibernate Jpamodelgen הנשלטת על ידי Spring Boot Dependencies עברה מהחבילה org.hibernate לחבילה org.hibernate.orm. ראה:

Spring Boot 2.7.5

XML

 

<dependency>
	<groupId>org.hibernate</groupId>
	<artifactId>hibernate-jpamodelgen</artifactId>
</dependency>

Spring Boot 3.0.2

XML

 

<dependency>
	<groupId>org.hibernate.orm</groupId>
	<artifactId>hibernate-jpamodelgen</artifactId>
</dependency>

Liquibase

כדי לסיים את התלבושות המרכזיות של הקבצים, עברנו את Liquibase מגרסה 4.9.1 ל-4.17.2. אין הבדל משמעותי חוץ משימוש במממת JAX-B. התלבושת צריכה להשתמש ב-JAX-B מ-Jakarta במקום מ-Javax (ראה ההפניה הבאה).

Spring Boot 2.7.5

XML

 

<dependency>
	<groupId>org.liquibase</groupId>
	<artifactId>liquibase-core</artifactId>
</dependency>

Spring Boot 3.0.2

XML

 

<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

Spring Boot 3.0.2 תלוי ב-Spring Data Release Train 2022.0.1 (ראה Spring Data 2022.0 – סיבוב השחרור של Turing), שם משתמשים ב-Spring Data JPA 3.0.1 עם השינויים הבולטים הבאים (ראה סיבוב השחרור):

  1. להחליף את בסיס Java ל-Java 17,
  2. להחליף את בסיס Jakarta ל-Jakarta EE 10 ו-
  3. להעלות ל-Hibernate 6

הערה: הגרסה שנהשתמשה בה קודם (במקרה שלנו) הייתה הגרסה 2.7.5.

Querydsl 5.0.0

גרסת Querydsl לא שונתה, אך מדובר בהשפעה דומה לגבי Liquibase. יש להשתמש בהפרדות מ-Jakarta במקום מ-Javax. לכן, יש להשתמש בהפרדה jakarta במקום ההפרדה הישנה jpa (ראה קישור זה הפניה).

Spring Boot 2.7.5

XML

 

<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

XML

 

<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>

מסקנה

מאמר זה כיסה את העלאת ה-Spring Boot האחרון ל-3.0.2 עבור JPA ו-Querydsl (בעת כתיבת המאמר). המאמר התחיל עם שינויים ב-Spring Framework וב-Spring Boot. לאחר מכן, כל השינויים ב-Hibernate ובטכנולוגיות קשורות מוזכרות. בסוף, דיברנו על השינויים הקטנים הקשורים ל-Spring Data 3.0.1 ו-Querydsl 5.0.0.

כל הקוד המדגים לעיל זמין במאגר ה-GitHub שלי.

הערה: יש גם מאמר קודם, מדריך העלאה ל-Spring Data Elasticsearch 5.0, המוקדש לעלאה דומה של Elasticsearch עם Spring Boot 3.

Source:
https://dzone.com/articles/upgrade-guide-to-spring-boot-3-for-spring-data-jpa-3-and-querydsl-5