官方 Spring 文档中的问题
Questions in the official Spring documentation
下面是来自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;
}
}
我对此有一些疑问。
Person withId(Long id)
例子中引用的构造函数不存在吗?
Person withId(Long id)
官方文档中有描述:"The same pattern is usually applied for other properties that are store managed but might have to be changed for persistence operations"。是不是可以这样理解:保存实例成功后,WithOutIdPerson
可以用于其他字段的变化并再次保存,SavedPerson
可以用于其他上层操作?
为什么实例中调用了工厂的最后一步of ()
??
谢谢~
问题 1
Person withId(Long id)
Does the referenced construction function not exist in the example?
这可能是文档中的错误,它应该如下所示:
Person withId(Long id) {
return new Person(id, this.firstname, this.lastname, this.birthday, this.age);
}
问题 2
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?
如果我理解你是对的,你想知道这是否可行:
Person p = Person.of( "Peter", "Parker", someDate);
Person saved = personRepository.save(p);
Person savedAgain = personRepository.save(p);
If Person
的id属性是由数据库设置的,是一个不可变的属性(它有一个wither 如示例中所示)那么 p
和 saved
(以及 savedAgain
)是不同的实体,并且两个 save
操作导致两行存储在数据库中并且 saved
和 savedAgain
具有不同的 ID,而 p
的 ID 仍然等于 null
.
问题 3
Why is the last step of the factory of()
called in the example?
实际上,示例代码中根本没有调用 of()
。
在代码的注释编号 (6) 中解释了为什么建议使用工厂方法而不是重载构造函数:
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.
如果没有工厂,您将有两个构造函数,并且需要 use @PersistenceConstructor
on one in order to tell Spring Data which one to use for instance creation。
下面是来自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;
}
}
我对此有一些疑问。
Person withId(Long id)
例子中引用的构造函数不存在吗?Person withId(Long id)
官方文档中有描述:"The same pattern is usually applied for other properties that are store managed but might have to be changed for persistence operations"。是不是可以这样理解:保存实例成功后,WithOutIdPerson
可以用于其他字段的变化并再次保存,SavedPerson
可以用于其他上层操作?为什么实例中调用了工厂的最后一步
of ()
??
谢谢~
问题 1
Person withId(Long id)
Does the referenced construction function not exist in the example?
这可能是文档中的错误,它应该如下所示:
Person withId(Long id) {
return new Person(id, this.firstname, this.lastname, this.birthday, this.age);
}
问题 2
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?
如果我理解你是对的,你想知道这是否可行:
Person p = Person.of( "Peter", "Parker", someDate);
Person saved = personRepository.save(p);
Person savedAgain = personRepository.save(p);
If Person
的id属性是由数据库设置的,是一个不可变的属性(它有一个wither 如示例中所示)那么 p
和 saved
(以及 savedAgain
)是不同的实体,并且两个 save
操作导致两行存储在数据库中并且 saved
和 savedAgain
具有不同的 ID,而 p
的 ID 仍然等于 null
.
问题 3
Why is the last step of the factory
of()
called in the example?
实际上,示例代码中根本没有调用 of()
。
在代码的注释编号 (6) 中解释了为什么建议使用工厂方法而不是重载构造函数:
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.
如果没有工厂,您将有两个构造函数,并且需要 use @PersistenceConstructor
on one in order to tell Spring Data which one to use for instance creation。