嗯,这个问题几乎说明了一切。如何使用JPARepository更新实体?
JPARepository只有一个保存方法,它不会告诉我它实际上是在创建还是在更新。例如,我向数据库用户插入一个简单的对象,该对象有三个字段:firstname、lastname和age
@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具有相同用户名和名字的用户实际上是相等的,并且现有实体应该被更新?重写equals并没有解决这个问题。
发布于 2012-08-09 18:43:42
实体的标识由它们的主键定义。由于firstname和lastname不是主键的一部分,因此如果User和firstname具有不同的lastname,则您不能告诉JPA将具有相同userId的JPA视为相等。
因此,如果要更新由其firstname和lastname标识的User,则需要通过查询找到该User,然后更改找到的对象的相应字段。这些更改将在事务结束时自动刷新到数据库,因此您不需要执行任何操作来显式保存这些更改。
编辑:
也许我应该详细说明一下JPA的整体语义。持久化API的设计主要有两种方法:
insert来插入对象,或者调用update来将对象的新状态保存到database.JPA遵循后一种方法。Spring Data JPA中的save()是由普通JPA中的merge()支持的,因此它可以像上面描述的那样管理您的实体。这意味着在具有预定义id的对象上调用save()将更新相应的数据库记录,而不是插入新的记录,这也解释了为什么save()不被称为create()。
发布于 2015-07-01 06:29:00
因为@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()。
您可以指定其他返回类型:
int -正在更新的记录数。
boolean -如果有正在更新的记录,则为true。否则为false。
注意:在Transaction中运行此代码。
发布于 2018-09-30 18:20:08
您可以简单地将此函数与save() JPAfunction一起使用,但是作为参数发送的对象必须包含数据库中现有的id,否则它将无法工作,因为当我们发送没有id的对象时,它会直接在数据库中添加一行,但是如果我们发送一个具有现有id的对象,它将更改数据库中已找到的列。
public void updateUser(Userinfos u) {
User userFromDb = userRepository.findById(u.getid());
// crush the variables of the object found
userFromDb.setFirstname("john");
userFromDb.setLastname("dew");
userFromDb.setAge(16);
userRepository.save(userFromDb);
}https://stackoverflow.com/questions/11881479
复制相似问题