DEV Community

Cover image for Spring Boot 3.0 and PostgreSQL Java19 Using Record with PageResponse
Weder Sousa
Weder Sousa

Posted on • Updated on

Spring Boot 3.0 and PostgreSQL Java19 Using Record with PageResponse

Introduction

Spring is one of the most widely used Java-based frameworks for enterprise application development.

The Spring Framework provides a broad and complete ecosystem of projects that encompasses several points that can help create applications, some of which are:

Spring Data: Simplifies access to relational data and NoSQL data stores

Spring Batch: Provides a powerful batch processing framework

Spring Security: Robust security framework to protect applications

Spring Cloud: Provides a set of tools for developers to implement common distributed system patterns such as Service Discovery, Configuration Management, Circuit Breaker, and more.

Spring Integration: An implementation of enterprise integration standards to facilitate integration with other enterprise applications using lightweight messaging and declarative adapters

Spring Boot Actuator: Getting the various details of an application running in production is crucial for many forms.

Spring is a very flexible and also customizable framework, having many ways to configure an application.

Although they have these facilities and many options, it can be a bit complex for developers who are in their first steps and who sometimes do not have specific skills in Object Oriented Programming.

Spring Boot comes to ease this problem of “Spring applications need complex configuration” that Spring Boot has powerful autoconfiguration mechanisms.

In this Article we will use as Tools:

  • Java 19
  • springboot
  • maven
  • docker-compose

Maven Dependencies:

  • Lombok
  • PostgreSQL Driver
  • spring web
  • Spring Data JPA
  • Spring Configuration Processor

Database server:

  • PostgreSQL v.15

IDE:

  • IntelliJ IDEA

To start, we will use https://start.spring.io/ to help you create the initial Project, below is an image of how the project will be started:

Image description

Java Release

https://www.oracle.com/br/news/announcement/oracle-releases-java-19-2022-09-20/, (09-20-2022), Download https://www. oracle.com/br/java/technologies/downloads/.

In this new version, it offers seven proposals for improving the JDK to increase developer productivity, improve the Java language with performance, stability and platform security.

JDK 19 features language improvements from the OpenJDK Amber project (Record Patterns and Pattern Matching for Switch); library for interoperating with non-Java code (Foreign Function and Memory API) and boosting vector instructions (Vector API) from the OpenJDK Project Panama; and the first views of Project Loom (Virtual Threads and Structured Concurrency), which will dramatically reduce the effort required to write and maintain concurrent high-performance Java applications.

Record type:

This language feature first appeared in version 14 https://openjdk.org/jeps/359 as experimental and continued until version 15 https://openjdk.org/jeps/384.

Definitively released in Java 16 https://openjdk.org/jeps/395.

A Record is nothing more than a type of class that stores data. It's the same idea of construction similar to a JavaBean, it has a constructor, attributes and accessor methods. However, it makes it impossible to change the class because it is immutable. The Record Type has the equals, hashCode and toString() methods.

What about the equals, hashCode and toString methods, do I have to declare them? Methods in Records are automatically generated for us, so there is no need to use libraries that do this work, one of the most used being, for example, Lombok.

However, the Record Type has some restrictions regarding this type of class:

  • A Record class does not have an extends clause
  • A Record class cannot be abstract
  • Attributes derived from the Record class are all final
  • Cannot declare instance fields
  • Cannot declare native methods
  • Aside from the above restrictions, a registration class

behaves like a normal class:

  • An instance of Record is created with the expression new
  • Can be declared as a generic type
  • Can declare static methods, attributes, and initializers
  • Can declare instance methods
  • Can implement interfaces
  • use annotations
  • Can be serialized and deserialized

All classes of type Record extend from the abstract class java.lang.Record

Records are a concise representation of the immutable data class.

Before Records, this is how we usually created an immutable class.

Using Records in SpringBoot 3

https://spring.io/blog/2022/11/24/spring-boot-3-0-goes-ga,

Result of 12 months of work and more than 5700 commits from 151 different individuals. Where many contributed and to all early adopters who provided vital feedback on the milestones.

What is striking about this release is that it is part of a major overhaul of Spring Boot since version 2.0 was released 4.5 years ago. It is also the first Spring Boot GA release that provides support for Spring Framework 6.0 and GraalVM.

Highlights of the new release include:

  • baselining for Java 17
  • Support for native imaging with GraalVM, replacing the experimental Spring Native project
  • Improved Observability with Micrometer and Micrometer Tracing
  • Support for Jakarta EE 10 with an EE 9

But what was it like before the inclusion of Records in Java?

Image description

Changing the code to use Records, just declare:

public record User(String name, String password){}
Enter fullscreen mode Exit fullscreen mode

Given the context of immutability, there is only one constructor with all attributes. There are also no setter methods.

User user = new User("root", "YzxNAws*");
Enter fullscreen mode Exit fullscreen mode

Another difference between the first design and this one using records is that the accessor methods don't use the terminology with “get” just the attribute name itself, that is, instead of getName(), just name();

String name = user.name();
Enter fullscreen mode Exit fullscreen mode

Using Change in an Application:

Image description

Changing the class to type Record:

Image description

Http Request/Response (Springboot3)

We typically create DTO classes with setters and getters to bind the incoming HTTP request payload because frameworks need a way to bind the request payload to the properties of the class.

SpringBoot by default uses the Jackson library to convert request/response payloads to/from JSON and Jackson 2.12 introduced support for records. So we can use records to bind incoming request payloads and also return records as response.

Here is a record with bean validation restrictions applied:

Using DTO(Data Transport Object):

Image description

Http request/response fetching book by id and Return Using created DTO.

Image description

The application can be found on github model project

How to run code from Github?

Download the Project, open it in your preferred IDE.

The project is configured to create the data in a Postgres database, which has been configured to push using docker-compose

Image description

 docker-compose -f docker-compose.yml up

Enter fullscreen mode Exit fullscreen mode

With the database created:

mvn spring-boot:run
Enter fullscreen mode Exit fullscreen mode

In the document folder, the json with all the calls via postman:

Image description

Conclusion

If we analyze that the Record type, has a simpler syntax due to the code generated, they can be useful in projects that are not using lombok, however if we analyze the OOP (Object Oriented Programming) issues coldly, the restrictions that can generate a discomfort for those who like to use OOP and restrictions deeply, leaves a gap in this context.

When I model objects that hold immutable data, the very concise syntax helps, however, in the general context, I didn't find an element that I liked, because there will be cases in which a regular class will be much more effective compared to Type Records.

References:

https://openjdk.java.net/jeps/395

https://www.baeldung.com/java-record-keyword

https://angiejones.tech/deserializing-api-responses-into-java-records/

https://medium.com/@gaozhixiang/records-vs-lombok-in-java-15-193306340ca0

https://softwaregarden.dev/en/posts/new-java/records/vs-lombok/

https://docs.oracle.com/en/java/javase/14/language/records.html

https://www.sivalabs.in/using-java-records-with-spring-boot-3/

https://www.infoq.com/br/articles/records-no-java-14/

https://en.wikipedia.org/wiki/Plain_old_Java_object

https://pt.wikipedia.org/wiki/Plain_Old_Java_Objects

https://www.baeldung.com/java-dto-pattern

Top comments (0)