Hello there i have a question concerning the right way of modelling immutable entities:
Consider this entity (edited as of the suggestion by Jens Schauder):
@Getter
@RequiredArgsConstructor(staticName = "of", access = AccessLevel.PACKAGE)
public final class Student {
private final @Id @Wither
long studentId;
@NotNull
@Size(min = 4, max = 20)
private final String userId;
@NotNull
@Min(0)
private final int matriculationNumber;
@NotNull
@Email
private final String eMail;
}
So this entity should be immutable and offers a static of
creation method. Also the RequiredArgsConstructor
builds a private constructor although it should create a package visible one for all final/non null fields per definition. In short i did an AllArgsConstructor
so to speak.
This document over here https://docs.spring.io/spring-data/jdbc/docs/current/reference/html/#mapping.fundamentals in detail the section about "Object creation internals" states 4 aspects for improved handling - "the constructor to be used by Spring Data must not be private" amongst others which are fulfilled in my opinion.
So my question: Is this pictured entity done right in both ways concerning immutabillity and spring data jdbc internals optimum mapping?
EDIT:
There seems to be a bug with lombok plugin in intellij, hindering the access = AccessLevel.PACKAGE
doing the right stuff. See here:
https://github.com/mplushnikov/lombok-intellij-plugin/issues/584
Although the issue is already closed a new version of the plugin is not available ...
This depends on your definition of "optimum mapping".
It should work, so this is already something.
But the optimization described in the docs cannot be applied because your constructor is private. Therefore you lose the 10% performance boost of that which it probably does not make it "optimal".
But the 10% boost is about the object instantiation. It is not about the roundtrip to the database which involves:
This makes it very likely that the gain from that optimization is well below 10% and in most cases nothing to worry about.
Of course, you will never really know until you made your own benchmarks with real data. For this, you would need to create an all args constructor which has at least package scope.