官方 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;
  }
}

我对此有一些疑问。

  1. Person withId(Long id)例子中引用的构造函数不存在吗?

  2. 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可以用于其他上层操作?

  3. 为什么实例中调用了工厂的最后一步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 如示例中所示)那么 psaved(以及 savedAgain)是不同的实体,并且两个 save 操作导致两行存储在数据库中并且 savedsavedAgain 具有不同的 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