Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to beautifully update a JPA entity in Spring Data?

So I have looked at various tutorials about JPA with Spring Data and this has been done different on many occasions and I am no quite sure what the correct approach is.

Assume there is the follwing entity:

package stackoverflowTest.dao;  import javax.persistence.*;  @Entity @Table(name = "customers") public class Customer {  @Id @GeneratedValue(strategy = GenerationType.AUTO) @Column(name = "id") private long id;  @Column(name = "name") private String name;  public Customer(String name) {     this.name = name; }  public Customer() { }  public long getId() {     return id; }  public String getName() {     return name; }  public void setName(String name) {     this.name = name; } } 

We also have a DTO which is retrieved in the service layer and then handed to the controller/client side.

package stackoverflowTest.dto;  public class CustomerDto {  private long id; private String name;  public CustomerDto(long id, String name) {     this.id = id;     this.name = name; }  public long getId() {     return id; }  public void setId(long id) {     this.id = id; }  public String getName() {     return name; }  public void setName(String name) {     this.name = name; } } 

So now assume the Customer wants to change his name in the webui - then there will be some controller action, where there will be the updated DTO with the old ID and the new name.

Now I have to save this updated DTO to the database.

Unluckily currently there is no way to update an existing customer (except than deleting the entry in the DB and creating a new Cusomter with a new auto-generated id)

However as this is not feasible (especially considering such an entity could have hundreds of relations potentially) - so there come 2 straight forward solutions to my mind:

  1. make a setter for the id in the Customer class - and thus allow setting of the id and then save the Customer object via the corresponding repository.

or

  1. add the id field to the constructor and whenever you want to update a customer you always create a new object with the old id, but the new values for the other fields (in this case only the name)

So my question is wether there is a general rule how to do this? Any maybe what the drawbacks of the 2 methods I explained are?

like image 515
Lukas Makor Avatar asked Sep 28 '16 07:09

Lukas Makor


People also ask

Which method is used to update entity in JPA?

We use the EntityManager. merge() method to update an entity. This method takes the entity to be saved as the parameter and return the merged entity back as the result.

Which method is used for update in JPA Repository?

Hibernate's @DynamicUpdate annotation, which dynamically rewrites the update query. JPA's @Column annotation, as we can disallow updates on specific columns using the updatable parameter.

Which is better CrudRepository or JpaRepository?

Crud Repository doesn't provide methods for implementing pagination and sorting. JpaRepository ties your repositories to the JPA persistence technology so it should be avoided. We should use CrudRepository or PagingAndSortingRepository depending on whether you need sorting and paging or not.


1 Answers

Even better then @Tanjim Rahman answer you can using Spring Data JPA use the method T getOne(ID id)

Customer customerToUpdate = customerRepository.getOne(id); customerToUpdate.setName(customerDto.getName); customerRepository.save(customerToUpdate); 

Is's better because getOne(ID id) gets you only a reference (proxy) object and does not fetch it from the DB. On this reference you can set what you want and on save() it will do just an SQL UPDATE statement like you expect it. In comparsion when you call find() like in @Tanjim Rahmans answer spring data JPA will do an SQL SELECT to physically fetch the entity from the DB, which you dont need, when you are just updating.

like image 146
Robert Niestroj Avatar answered Sep 20 '22 00:09

Robert Niestroj