Java Record

What is a Record?

In Java, it’s common to have classes that exist solely to carry data, i.e., classes with fields, simple methods like getters, equals(), hashCode(), and toString(). Before records, defining such classes could be quite verbose.

A record is a restricted form of class that provides a concise way to define such classes. When you define a record, the Java compiler automatically implements several standard methods for you.

Characteristics of Records:

  1. Immutable: Records are implicitly final and their fields are also final. Thus, once a record is created, you cannot modify its state.
  2. No Subclassing: You cannot explicitly extend a record, and records cannot extend other classes.
  3. Auto-generated Standard Methods: The compiler automatically generates methods like equals(), hashCode(), and toString() based on the fields of the record.
  4. Explicit fields: The record’s header declares its fields, and these are the only fields allowed.
public record Point(int x, int y) { }

This simple declaration creates:

  • A record with two fields, x and y.
  • A constructor taking two parameters to initialize these fields.
  • Getters for these fields (x() and y()).
  • An equals() method that checks for equality based on the values of x and y.
  • A hashCode() method based on the values of x and y.
  • A toString() method that returns a string in the format Point[x=<value>, y=<value>].
public class TestRecords {
    public static void main(String[] args) {
        Point p1 = new Point(5, 10);
        Point p2 = new Point(5, 10);
        
        System.out.println(p1); // Prints: Point[x=5, y=10]
        System.out.println(p1.equals(p2)); // Prints: true
    }
}

Customizing Records:

While records are meant to be simple data carriers, you can still customize them:

Custom Constructors:

You can define custom constructors, but they should call the canonical constructor:

public record Rectangle(int width, int height) {
    public Rectangle {
        if (width < 0 || height < 0) {
            throw new IllegalArgumentException("Dimensions should be positive");
        }
    }
}

Adding Methods:

You can add methods to a record:

public record Point(int x, int y) {
    public double distanceFromOrigin() {
        return Math.sqrt(x * x + y * y);
    }
}

Implementing Interfaces:

Records can implement interfaces:

public record NamedPoint(int x, int y, String name) implements Comparable<NamedPoint> {
    @Override
    public int compareTo(NamedPoint other) {
        return name.compareTo(other.name);
    }
}

Things to Remember:

Record components are final by default.

Records can’t be abstract.

Records can’t extend other classes.

You can’t declare instance fields in a record that aren’t record components.

Records are a significant step toward making Java more expressive and less verbose, especially for common coding patterns.

Caveats and Considerations for using Record with JPA:

Annotations: With records, you can’t annotate fields directly since they’re declared in the record header. If you need to add JPA annotations (like @Id, @GeneratedValue, etc.), they should be added to the accessor methods (getters) of the record.

Immutability: Records are inherently immutable, which means all their fields are final. This behavior aligns with the principle of immutability in entity design but can complicate scenarios where you want to change an entity’s state after it has been constructed.

NoArgs Constructor: JPA typically requires a noargs constructor, which records don’t provide out of the box. Hibernate’s (a popular JPA implementation) team has been working to support records, so expect improvements in this area. If your JPA provider doesn’t support records yet, consider using DTOs (Data Transfer Objects) alongside your entities.

Experimental Support: As mentioned earlier, while Spring Data started introducing experimental support for records, this might not be fully mature or cover all scenarios. Always refer to the latest Spring Data documentation and check for compatibility and best practices.




Subscribe To Our Newsletter
You will receive our latest post and tutorial.
Thank you for subscribing!

required
required


Leave a Reply

Your email address will not be published. Required fields are marked *