JPA allows fields to be Basic Types or Embeddable Classes, the latter of which can be a record. An existing pattern for type safety is to wrap a Java primitive types, UUID, or String (all of which are basic types) in a record. For example, instead of representing all the IDs as longs or UUIDs and all names as String, one can use record BookId(long id), record CatalogId(long id), record BookName(String name), and record StreetName(String name) as a means to enforce correctness.
Currently, this is possible through embeddable types:
@Entity
public class Library {
@EmbeddedId
LibraryId id;
@Embedded
LibraryName name;
@Embedded
StreetName streetName;
@Embedded
CatalogId catalogId;
}
// no annotation needed according to @EmbeddedId's docs
public record LibraryId(UUID libraryId) {}
@Embeddable
public record StreetName(String streetName) {}
@Embeddable
public record LibraryName(String name) {}
@Embeddable
public record CatalogId(long catalogId) {}
The use of records in such a way will probably increase in popularity when value classes are introduced, which will minimize the performance impact of the wrapper indirection.
I'd like to explore the idea of extending the allowed persistent fields to include "records of Basic Types". This will eliminate the "noise"/ceremony of the @Embeddable <-> @Embedded annotations. In terms of implementation, there is no ambiguity - the field is created through the canonical constructor and retrieved through its accessor. This change is also backwards compatible. The risk here is increasing the complexity of the mental model of the user and the code as it may not be clear if a type requires the annotations or not. However, this is part of the user's domain and their responsibility, and the current list of allowed non-primitive types is already relatively arbitrary (I use this term loosely, it's various time-related classes).
JPA allows fields to be Basic Types or Embeddable Classes, the latter of which can be a
record. An existing pattern for type safety is to wrap a Java primitive types,UUID, orString(all of which are basic types) in a record. For example, instead of representing all the IDs aslongs orUUIDs and all names asString, one can userecord BookId(long id),record CatalogId(long id),record BookName(String name), andrecord StreetName(String name)as a means to enforce correctness.Currently, this is possible through embeddable types:
The use of records in such a way will probably increase in popularity when value classes are introduced, which will minimize the performance impact of the wrapper indirection.
I'd like to explore the idea of extending the allowed persistent fields to include "records of Basic Types". This will eliminate the "noise"/ceremony of the
@Embeddable<->@Embeddedannotations. In terms of implementation, there is no ambiguity - the field is created through the canonical constructor and retrieved through its accessor. This change is also backwards compatible. The risk here is increasing the complexity of the mental model of the user and the code as it may not be clear if a type requires the annotations or not. However, this is part of the user's domain and their responsibility, and the current list of allowed non-primitive types is already relatively arbitrary (I use this term loosely, it's various time-related classes).