Records -- Using them as JPA entities and validating them with Bean Validation

Gunnar Morling gunnar at hibernate.org
Mon Apr 9 20:39:36 UTC 2018


Hi,

It's with great interest that I've read the proposal for records / data
classes, I think it could be a very useful addition to the language.

One thing I'm very curious about is whether records could be used as JPA
entities. From a first glance, the goals of the records proposal would be
beneficial for JPA, too (less "ceremony" for defining POJOs). Some of the
issues discussed in Brian's mail "Records -- current status" [1] would make
records less useful for JPA, though:

  * No custom equals()/hashCode(): that'd be the biggest obstacle for using
records as JPA entities, as users often wish to implement those methods
based on an entity's business key (e.g. the "isbn" property of a Book
entity) or based on the id property of the entity. I.e. for JPA the ability
to override equals()/hashCode() would be vital

  * Concrete records are final: that'd prevent records to be used for
modelling some inheritance hierarchies. While not ideal, I don't think it'd
be too big of a problem in practice, as from what I see, oftentimes users
try to avoid inheritance in their persistent domain models anyways

  * Custom methods: It's not fully clear to me, whether additional methods
would be allowed on records or not; For JPA, that'd be desirable, as users
often add methods with entity-specific logic to their entities

  * Annotation semantics: I couldn't find any example of records with
annotations, but IIUC, something like

        @Entity record Book(@Id long id, String isbn) { ... }

    would desugar into

        class @Entity public class Book { private @Id long id, private
String isbn; ... };

    For the JPA entity use case it'd be helpful to have an option to lift
annotations to the corresponding getters instead of the fields (as the
location of the @Id annotation controls the default strategy -- field vs.
property -- for reading/writing entity state). Similarly, Bean Validation
would benefit from such option.

  * Lifting annotations to corresponding constructor parameters: this ties
into the discussion of precondition validation, for which Bean Validation
(JSR 380 [3]) might be one interesting declarative alternative to the more
imperative means discussed so far. Bean Validation supports the validation
of constrained constructor parameters:

        public Book(@Positive long id, @NotNull title) { ... }

    If constructor invocation is channeled through some sort of interceptor
(e.g. via AspectJ), the parameter values can be validated automatically
upon invocation. One advantage of this declarative annotation-based
approach is that it makes the required invariants very transparent to the
caller of such constructor. For this to work, it'd be a requirement to lift
any Bean Validation annotations from the record state to the generated
constructor.

    Thinking further, it'd be very interesting to have a way for weaving in
the code calling the Bean Validation engine for such constructor invocation
into the desugared code created for the record type. I see how Project
Amber likely wouldn't want to establish a dependence to an API such as Bean
Validation, but it might be interesting to explore whether the desugaring
step could be made extensible, allowing 3rd parties to plug in such
extended behaviour.

It might well be that records indeed turn out to be not a good fit to be
used as JPA entities, but I wanted to bring these questions/thoughts here
to gain some clarity. Being able to put Bean Validation constraints to
records would IMO be useful in any case.

Thanks for your consideration,

--Gunnar

[1]
http://mail.openjdk.java.net/pipermail/amber-spec-experts/2018-March/000400.html
[2] http://cr.openjdk.java.net/~briangoetz/amber/datum.html
[3] https://jcp.org/en/jsr/detail?id=380


More information about the amber-dev mailing list