How to update an object using spring -data-jpa?

It is good that the question as a whole speaks about everything. Using JPARepository how to update an object?

JPARepository has only a save method, which does not tell me if it really creates or updates. For example, I insert a simple object into the User database, which has three fields: first and last name 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 just โ€œsaveโ€, which at the moment is an insert:

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

Good, all is well. Now I want to update this user, say, change his age. Well, I could use Query for QueryDSL or NamedQuery, regardless. But, given that I just want to use spring-data-jpa and JPARepository, how do I say that instead of pasting I want to do an update?

In particular, how can I tell spring -data-jpa that users with the same username and first name are actually EQUAL and that the object is supposed to be updated. The redefinition of peers did not work.

Thank!

+167
java spring-data-jpa jpa
Aug 09 '12 at 10:33
source share
9 answers

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

So, if you want to update the User , identified by its firstname and lastname , you need to find the User request by the request, and then change the corresponding fields of the found object. These changes will be automatically deleted to the database at the end of the transaction, so you do not need to do anything to save these changes explicitly.

EDIT:

Perhaps I should elaborate on the general semantics of JPA. There are two main approaches to developing persistence APIs:

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

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

JPA follows a later approach. save() in Spring JPA data is supported by merge() in a simple JPA, so it manages your entity as described above. This means that calling save() object with a predefined identifier will update the corresponding database record rather than insert a new one, and also explains why save() not called create() .

+180
Aug 09 2018-12-12T00:
source share

Since @axtavt's answer focuses on JPA not spring-data-jpa

To update an object by query, saving is inefficient because it requires two queries, and perhaps the query can be quite expensive, as it can join other tables and load all collections that have fetchType=FetchType.EAGER

spring-data-jpa supports update operation.
You must define this method in the repository interface and annotate it using @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 a user query, and @Modifying is for telling spring-data-jpa that this query is an update operation and requires executeUpdate() not executeQuery() .

+111
Jun 30 '15 at
source share

You can simply use this function with save () JPAfunction, but the object sent as a parameter must contain an existing identifier in the database, otherwise it will not work, because save (), when we send an object without an identifier, adds the line directly in the database, but if we send an object with an existing identifier, it will change the columns already found in the database.

 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); } 
+18
Sep 30 '18 at 10:20
source share

As others have already mentioned, save() contains create and update operations.

I just want to add an addition about what is behind the save() method.

First, let's see the extension / implementation CrudRepository<T,ID> , enter image description here

Ok, let's check the save() implementation on SimpleJpaRepository<T, ID> ,

 @Transactional public <S extends T> S save(S entity) { if (entityInformation.isNew(entity)) { em.persist(entity); return entity; } else { return em.merge(entity); } } 

As you can see, it will first check if the ID exists or not, if the entity already exists, only the update method will happen using the merge(entity) method, otherwise the new record will be inserted by the persist(entity) method.

+13
Dec 11 '18 at 3:38
source share

Using spring -data-jpa save (), I had the same problem as @DtechNet. I mean, each save () created a new object instead of updating. To solve this problem, I had to add a "version" filed to the entity and its associated table.

+7
Dec 06 '15 at 18:54
source share

This is how I solved the problem:

 User inbound = ... User existing = userRepository.findByFirstname(inbound.getFirstname()); if(existing != null) inbound.setId(existing.getId()); userRepository.save(inbound); 
+5
Sep 21 '17 at 15:40
source share

The Spring data save() method will help you perform both adding a new element and updating an existing element.

Just call save() and enjoy life :))

+4
Jun 03 '19 at 10:06 on
source share
 public void updateLaserDataByHumanId(String replacement, String humanId) { List<LaserData> laserDataByHumanId = laserDataRepository.findByHumanId(humanId); laserDataByHumanId.stream() .map(en -> en.setHumanId(replacement)) .collect(Collectors.toList()) .forEach(en -> laserDataRepository.save(en)); } 
+1
Mar 26 '19 at 10:42
source share

In particular, how can I tell spring-data-jpa that users who have the same username and name are actually equal and that it should update the entity. The redefinition of peers did not work.

For this specific purpose, you can enter a compound key, for example:

 CREATE TABLE IF NOT EXISTS 'test'.'user' ( 'username' VARCHAR(45) NOT NULL, 'firstname' VARCHAR(45) NOT NULL, 'description' VARCHAR(45) NOT NULL, PRIMARY KEY ('username', 'firstname')) 

Display:

 @Embeddable public class UserKey implements Serializable { protected String username; protected String firstname; public UserKey() {} public UserKey(String username, String firstname) { this.username = username; this.firstname = firstname; } // equals, hashCode } 

Here's how to use it:

 @Entity public class UserEntity implements Serializable { @EmbeddedId private UserKey primaryKey; private String description; //... } 

JpaRepository will look like this:

 public interface UserEntityRepository extends JpaRepository<UserEntity, UserKey> 

Then you can use the following idiom: accept a DTO with user information, extract the name and name and create a UserKey, then create a UserEntity with this composite key and then call Spring Data save (), which should fix everything for you.

0
Jul 25 '19 at 12:03
source share



All Articles