0

这是官方文档中的一个例子(你需要向下滚动一点):</p>

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) 官方文档中有这样的描述:“相同的模式通常适用于存储管理的其他属性,但可能需要更改以进行持久化操作”。是不是可以这样理解:成功保存实例后,WithOutIdPerson可以用于其他字段更改并再次保存,SavedPerson还可以用于其他上层操作?

  3. 为什么of ()在示例中调用工厂的最后一步?

谢谢~

4

1 回答 1

1

问题 1

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

这可能是文档中的一个错误,它应该如下所示:

Person withId(Long id) {                                                  
    return new Person(id, this.firstname, this.lastname, this.birthday, this.age);
}

问题2

成功保存实例后,WithOutIdPerson是否可以用于其他字段更改并再次保存,SavedPerson是否可以用于其他上层操作?

如果我理解你是正确的,你想知道这是否可行:

Person p = Person.of( "Peter", "Parker", someDate);
Person saved  = personRepository.save(p);
Person savedAgain = personRepository.save(p);

如果id 属性Person由数据库设置并且它是不可变属性(它具有示例中给出的枯萎p),则和saved(and savedAgain) 是不同的实体,并且这两个save操作导致两行存储在数据库中,saved并且savedAgain具有不同的 id 并且pid 仍然等于null.

问题 3

为什么of()在例子中调用了工厂的最后一步?

实际上,of()在示例代码中根本没有调用。为什么推荐使用工厂方法而不是重载的构造函数在代码的注释编号 (6) 中进行了解释:

该类公开了一个工厂方法和一个用于创建对象的构造函数。这里的核心思想是使用工厂方法而不是额外的构造函数来避免需要通过@PersistenceConstructor 对构造函数进行消歧。相反,属性的默认设置是在工厂方法中处理的。

如果没有工厂,您将有两个构造函数,并且需要使用@PersistenceConstructor一个来告诉 Spring Data 使用哪一个来创建实例

于 2019-12-10T06:52:38.893 回答