Here is an example from the official documentation (You need to scroll down a little):
class Person {
private final @Id Long id;
private final String firstname, lastname;
private final LocalDate birthday;
private final int age;
private String comment;
private @AccessType(Type.PROPERTY) String remarks;
static Person of(String firstname, String lastname, LocalDate birthday) {
return new Person(null, firstname, lastname, birthday,
Period.between(birthday, LocalDate.now()).getYears());
}
Person(Long id, String firstname, String lastname, LocalDate birthday, int age) {
this.id = id;
this.firstname = firstname;
this.lastname = lastname;
this.birthday = birthday;
this.age = age;
}
Person withId(Long id) {
return new Person(id, this.firstname, this.lastname, this.birthday);
}
void setRemarks(String remarks) {
this.remarks = remarks;
}
}
I have a few questions about this.
Person withId(Long id)
Does the referenced construction function not exist in the example?
Person withId(Long id)
There is a description in the official documentation :"The same pattern is usually applied for other properties that are store managed but might have to be changed for persistence operations". Can I understand it this way: After successfully saving the instance, WithOutIdPerson
can be used for other field changes and saved again, and SavedPerson
can be used for other upper level operations?
Why is the last step of the factory of ()
called in the example??
Thank you~
Person withId(Long id)
Does the referenced construction function not exist in the example?
That is probably a bug in the documentation, it should look like this:
Person withId(Long id) {
return new Person(id, this.firstname, this.lastname, this.birthday, this.age);
}
After successfully saving the instance,
WithOutIdPerson
can be used for other field changes and saved again, andSavedPerson
can be used for other upper level operations?
If I understand you correct you are wondering if this would work:
Person p = Person.of( "Peter", "Parker", someDate);
Person saved = personRepository.save(p);
Person savedAgain = personRepository.save(p);
If the id attribute of Person
is set by the database and it is an immutable attribute (it has a wither as given in the example) then p
and saved
(and savedAgain
) are distinct entities and the two save
operations result in two rows being stored in the database and saved
and savedAgain
having distinct ids and p
has still id equal to null
.
Why is the last step of the factory
of()
called in the example?
Actually, of()
isn't called at all in the example code.
Why a factory method is recommended over overloaded constructors is explained in note number (6) of the code:
The class exposes a factory method and a constructor for object creation. The core idea here is to use factory methods instead of additional constructors to avoid the need for constructor disambiguation through @PersistenceConstructor. Instead, defaulting of properties is handled within the factory method.
Without the factory you would have two constructors and would need to use @PersistenceConstructor
on one in order to tell Spring Data which one to use for instance creation.