我如何使用spring更新实体

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

JPARepository只有一个保存方法,它不会告诉我它是否实际创建或更新。 例如,我向数据库用户插入一个简单的对象,该用户有三个字段:名字和姓氏以及年龄:

 @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;
  }
}

然后我简单地“保存”,实际上这是一个插入。

 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,并且它应该更新实体。 重写等于不起作用。

谢谢!


实体的身份由其主键定义。 由于firstnamelastname是不是主键的部分,你不能告诉JPA对待User使用相同的S firstname S和lastname ■如果他们有不同的作为平等的userId秒。

所以,如果你想更新User通过其标识firstnamelastname ,你需要找到User通过查询,然后改变你的对象找到合适的领域。 这些更改将在事务结束时自动刷新到数据库,以便您无需执行任何操作即可明确保存这些更改。

编辑:

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

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

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

  • JPA遵循后面的方法。 Spring Data中的save() JPA由纯JPA中的merge()支持,因此它使您的实体按上述方式进行管理。 这意味着对具有预定义id的对象调用save()将更新相应的数据库记录,而不是插入新的数据库记录,并解释为什么save()不称为create()


    由于@axtavt的答案侧重于JPA而不是spring-data-jpa

    要通过查询来更新实体,保存效率并不高,因为它需要两个查询,并且可能查询的代价可能非常昂贵,因为它可能会加入其他表并加载任何具有fetchType=FetchType.EAGER

    Spring-data-jpa支持更新操作。
    您必须在Repository接口中定义该方法,并使用@Query@Modifying对其进行注释。

    @Modifying
    @Query("update User u set u.firstname = ?1, u.lastname = ?2 where u.id = ?3")
    void setUserInfoById(String firstname, String lastname, Integer userId);
    

    @Query用于定义自定义查询, @Modifying用于告诉spring-data-jpa此查询是更新操作,它需要executeUpdate()而不是executeQuery()


    使用spring-data-jpa save(),我遇到了与@DtechNet相同的问题。 我的意思是每个save()都是创建新对象而不是更新。 为了解决这个问题,我不得不在实体和相关表中添加“版本”。

    链接地址: http://www.djcxy.com/p/89589.html

    上一篇: How do I update an entity using spring

    下一篇: @Version annotation