java - 如何使用 spring-data-jpa 更新实体?

标签 java jpa spring-data-jpa

这个问题几乎说明了一切。使用 JPARepository 如何更新实体?

JPARepository 只有一个 save 方法,它并没有告诉我它实际上是创建还是更新。比如我在数据库User中插入一个简单的Object,它有三个字段:firstnamelastnameage:

 @Entity
 public class User {

  private String firstname;
  private String lastname;
  //Setters and getters for age omitted, but they are the same as with firstname and lastname.
  private int age;

  @Column
  public String getFirstname() {
    return firstname;
  }
  public void setFirstname(String firstname) {
    this.firstname = firstname;
  }

  @Column
  public String getLastname() {
    return lastname;
  }
  public void setLastname(String lastname) {
    this.lastname = lastname;
  }

  private long userId;

  @Id
  @GeneratedValue(strategy=GenerationType.AUTO)
  public long getUserId(){
    return this.userId;
  }

  public void setUserId(long userId){
    this.userId = userId;
  }
}

然后我简单地调用save(),此时它实际上是插入数据库:

 User user1 = new User();
 user1.setFirstname("john"); user1.setLastname("dew");
 user1.setAge(16);

 userService.saveUser(user1);// This call is actually using the JPARepository: userRepository.save(user);

到目前为止一切顺利。现在我想更新这个用户,比如改变他的年龄。为此,我可以使用查询,无论是 QueryDSL 还是 NamedQuery。但是,考虑到我只想使用 spring-data-jpa 和 JPARepository,我该如何告诉它我想要更新而不是插入?

具体来说,我如何告诉 spring-data-jpa 具有相同用户名和名字的用户实际上是 EQUAL 并且应该更新现有实体?覆盖 equals 并没有解决这个问题。

最佳答案

实体的身份由它们的主键定义。从 firstnamelastname不是主键的一部分,您不能告诉 JPA 处理 User s 与 firstname 相同和 lastname s 相等,如果它们有不同 userId秒。

所以,如果您想更新 User由其 firstname 标识和 lastname , 你需要找到 User通过查询,然后更改您找到的对象的适当字段。这些更改将在事务结束时自动刷新到数据库,因此您无需执行任何操作来显式保存这些更改。

编辑:

也许我应该详细说明 JPA 的整体语义。设计持久性 API 有两种主要方法:

  • 插入/更新方法。当你需要修改数据库时,你应该显式调用持久化 API 的方法:你调用 insert插入对象,或 update将对象的新状态保存到数据库中。

  • 工作单元方法。在这种情况下,您有一组由持久性库管理的对象。您对这些对象所做的所有更改都将在工作单元结束时自动刷新到数据库中(即典型情况下在当前事务结束时)。当您需要向数据库中插入新记录时,您使相应的对象托管Managed 对象由它们的主键标识,因此如果您使用预定义的主键 managed 制作一个对象,它将与相同 id 的数据库记录相关联,并且此对象的状态将自动传播到该记录。

JPA 遵循后一种方法。 save()在 Spring Data 中,JPA 由 merge() 支持在普通的 JPA 中,因此它使您的实体 managed 如上所述。这意味着调用 save()在具有预定义 id 的对象上将更新相应的数据库记录而不是插入新记录,并解释了原因 save()不叫 create() .

关于java - 如何使用 spring-data-jpa 更新实体?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11881479/

相关文章:

排序不适用于 Spring Boot 中的 Pageable

java - 节点 : org. hibernate.hql.internal.ast.tree.MethodNode 没有数据类型

java - 编译器无法识别我的变量

java - 错误 :Execution failed for task ':app:transformClassesWithMultidexlistForDebug' . >

java - 以编程方式设置特定的 bean 对象 - Spring DI

java - 框架集中 iframe 中的 NoSuchElementException

java - 将 LocalDate.MAX 转换为日期

java - 又是: How to solve 'Repeated column in mapping for collection' ?

exception - javax.persistence.PersistenceException : Unable to build entity manager factory

java - 我可以使用 spring 数据标准接口(interface)方法添加条件吗