How do I update an entity using spring

Well the question pretty much says everything. Using JPARepository how do I update an entity?

JPARepository has only a save method, which does not tell me if it's create or update actually. For example, I insert a simple Object to the database User, which has three fields: firstname and lastname and 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;
  }
}

Then I simply "save", which at this point is an insert actually:

 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);

Ok all is good. Now I want to update this user, say change his age. Well I could use a Query for that either QueryDSL or NamedQuery, whatever. But, considering I just want to use spring-data-jpa and the JPARepository, how do I tell it that instead of an insert I want to do an update?

Specifically how do I tell spring-data-jpa that users that have the same username and firstname are actually EQUAL and that it is supposed to update the entity. Overriding equals did not work.

Thank You!


Identity of entities is defined by their primary keys. Since firstname and lastname are not parts of the primary key, you cannot tell JPA to treat User s with the same firstname s and lastname s as equal if they have different userId s.

So, if you want to update a User identified by its firstname and lastname , you need to find that User by a query, and then change appropriate fields of the object your found. These changes will be flushed to the database automatically at the end of transaction, so that you don't need to do anything to save these changes explicitly.

EDIT:

Perhaps I should elaborate on overall semantics of JPA. There are two main approaches to design of persistence APIs:

  • insert/update approach . When you need to modify the database you should call methods of persistence API explicitly: you call insert to insert an object, or update to save new state of the object to the database.

  • Unit of Work approach . In this case you have a set of objects managed by persistence library. All changes you make to these objects will be flushed to the database automatically at the end of Unit of Work (ie at the end of the current transaction in typical case). When you need to insert new record to the database, you make the corresponding object managed. Managed objects are identified by their primary keys, so that if you make an object with predefined primary key managed, it will be associated with the database record of the same id, and state of this object will be propagated to that record automatically.

  • JPA follows the later approach. save() in Spring Data JPA is backed by merge() in plain JPA, therefore it makes your entity managed as described above. It means that calling save() on an object with predefined id will update the corresponding database record rather than insert a new one, and also explains why save() is not called create() .


    Since the answer by @axtavt focuses on JPA not spring-data-jpa

    To update an entity by querying then saving is not efficient because it requires two queries and possibly the query can be quite expensive since it may join other tables and load any collections that have fetchType=FetchType.EAGER

    Spring-data-jpa supports update operation.
    You have to define the method in Repository interface.and annotated it with @Query and @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 is for defining custom query and @Modifying is for telling spring-data-jpa that this query is an update operation and it requires executeUpdate() not executeQuery() .


    Using spring-data-jpa save(), I was having same problem as @DtechNet. I mean every save() was creating new object instead of update. To solve this I had to add "version" filed to entity and related table.

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

    上一篇: 春季数据休息

    下一篇: 我如何使用spring更新实体