دليل الترقية إلى إصدار Spring Boot 3.0 لـ Spring Data JPA و Querydsl

العام الماضي، كتبت مقالتين حول JPA Criteria و Querydsl (انظر مقالات المقدمة و الممتلكات المتغيرة). منذ نهاية العام الماضي، أصدرت Spring Boot إصدارًا رئيسيًا جديدًا هو 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).
  • رفع إلى Spring Framework 6 (انظر أعلاه).
  • ترقية إلى Hibernate 6 (انظر أدناه).
  • الترحيل من تبعيات JavaEE إلى تبعيات Jakarta EE – هذا ليس مهم في حالتنا لأننا لا نعتمد على Java المصمم للشركات هنا، ولكن قد يؤثر على العديد من التبعيات (على سبيل المثال، واجهة برمجة التطبيقات الخدمة، التحقق، البرمجة الديناميكية، 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) للعديد من الواجهات برمجة التطبيقات (على سبيل المثال، 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;

هيبرنيتش 6.1.6

تغيير رئيسي آخر في Spring Boot 3 هو الترقية من Hibernate 5.6 إلى Hibernate 6.1. يمكن العثور على التفاصيل حول Hibernate 6.1 هنا أو داخل ملاحظات الإصدار.

بصراحة، لم أنتبه لهذا التغيير حتى اضطررت لإصلاح اختبار واحد فشل بسبب حجم نتيجة مختلف (انظر الإصلاح في فئة CountryRepositoryCustomTests). تُرجع التنفيذ بواسطة هيبرنيتش 6 الجديد عددًا أقل من الكيانات من ذي قبل.

يجدر بالذكر تغييران هنا بناءً على هذا التحقيق. لنبدأ بالتسجيل أولاً.

تسجيل

تم تغيير مستندات التسجيل في Hibernate من org.hibernate.type إلى org.hibernate.orm.jdbc (انظر هذه المرجعية و هذه المرجعية).

ملاحظة: يمكن العثور على جميع الإعدادات المتاحة في فئة org.hibernate.cfg.AvailableSettings.

هايبرنات 5

كان هناك مستند تسجيل واحد للقيم المخفية والمستخرجة.

Properties files

 

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

هايبرنات 6

غيرت Hibernate 6 الحزمة الرئيسية وفرتها إلى مستندي تسجيل مختلفين من أجل التمييز بين العملية -> ما القيمة التي يجب تسجيلها.

Properties files

 

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

نموذج الاستعلام الدلالي

مع إصلاح التسجيل، تم التأكد من أن Hibernate فعلاً يستخرج سجلين من قاعدة البيانات:

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 الآن بإرجاع النتيجة المطافة.

مولد JPA في Hibernate

تم نقل متعلقات Maven لـ 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 Release Notes)، حيث يتم استخدام 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. ولذلك، يجب أن تستخدم وايفاية Querydsl المصطلح 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