“Do. Or do not. There is no try.”
Master Yoda
Since the introduction of Java Records in Java 14 (JEP 359), their support in many frameworks has continued to grow. Support is now so great that we should consider banning Lombok from all our projects.
Java Records are a special type of class in Java that are used to model data in a compact and efficient way. They provide a faster and easier way to create immutable data objects without having to manually write boilerplate code such as getter, setter, equals()
, hashCode()
and toString()
methods.
Java Records are characterized by Immutability, Data-Centricity and Compact Representation.
- Immutability: Records create immutable data objects. The data fields declared in a record are final and the state of a record object cannot be changed after it has been created.
- Data-Centricity: Records are primarily designed to hold data. They are particularly suitable for data transfer objects (DTO), value objects and simple data models: Records are primarily designed to hold data. They are particularly suitable for data transfer objects (DTO), value objects and simple data models.
- Compact Representation: The record syntax is minimalistic and records automatically generate all necessary methods such as
equals()
,hashCode()
andtoString()
. This increases the readability and maintainability of the code.
Before Java Records were available in the Java language, POJOS had to be used instead. These classes require all the boiler-plate code that can be saved with Java Records. Since we developers are lazy, Lombok is used in many projects.
Lombok is a Java library that is used to reduce boilerplate code and automatically generates useful code constructs such as getters, setters, constructors and other implementations in the bytecode using annotations. It thus improves readability, reduces the risk of errors and increases consistency by reducing the need for manual method writing.
However, Lombok can cause problems because the effects of the annotations are not fully understood. For example, @Data
is repeatedly used for entity classes and then leads to unexpected errors.
The obvious advantages of Java Records over Lombok are
- Built-in language support: Since Java Records is a native Java feature, language support for Java Records will remain constant, while libraries such as Lombok can sometimes lead to incompatibilities due to changes in the Java compiler.
- Simplicity and readability: Java Records allow a clear and simple definition of immutable data objects without boilerplate code. No additional annotations are required, which makes the code clean and easy to understand.
- No additional dependencies: By using Java Records, external dependencies such as Lombok are eliminated, which simplifies dependency management in large projects and can improve build times.
New Java features only really unfold their potential when they are used in the familiar frameworks. Some important ones and their support are listed below.
Hibernate/JPA Due to their nature, Java Records cannot be used as Entity classes. As neither the classes nor their attributes may be final, an entity can only be represented by a normal Java class. However, there are two possible uses for Java Records in this environment. Firstly, they can be used as embeddable objects in entities and they can replace the classic DTO in projections.
Jackson Java Records can be serialized and deserialized by Jackson. Jackson annotations are also possible, as shown in the following example.
record Ancestor( @JsonProperty("first_name") String firstName, @JsonProperty("last_name") String lastName, Adressaddress, LocalDate birthday) { }
Spring Boot Since Spring Boot is based on JPA and Jackson in many places, their Java Record support can also be used in Spring Boot. They are particularly helpful for @ConfigurationProperties
classes and the payload of @Controller
classes. The following example of a @ConfigurationProperties
class shows not only the very compact representation of the configuration, but also the additional support provided by the Java Bean Validation Framework.
@ConfigurationProperties("anchestor") @Validated public record AncestorProperties(@NotLocalHost URI uri, Generations generations) { public record Generations(@Positive @Max(12) int max) { } }
FreshMarker is a little-known but self-developed framework that has enabled the use of Java Records in the model for some time now.
In addition to these frameworks, there are many others with Java Record support. A good reason to remove Lombok. Anyone who comes up with the argument that their project JDK does not yet contain any Java Records should switch as soon as possible to Java 17 or, even better, Java 21. Even the Premier Support for your JDK has already expired!