Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use hibernate @DynamicUpdate with spring data jpa?

I am using spring data-jpa. I want update only one column.

My repository is;

public interface UserRepository extends JpaRepository<User,Long> {
}

my Service is;

public User save(User user) {
    return userRepository.save(user);
}

my Entity;

@Entity
@DynamicUpdate(true)
public class User implements Serializable {
    // column definitions, etc.
}

How can I update only one column in User?

like image 264
Ravi Jangid Avatar asked Sep 04 '18 08:09

Ravi Jangid


People also ask

Can we use Spring Data JPA with Hibernate?

This is the type of code Spring Data JPA helps to avoid. Spring Data JPA is really a set of dependencies that makes it easier to work with a JPA provider. Hibernate is one of several JPA providers. This means you can use Spring Data JPA without using Hibernate (if you really wanted to).

What is @DynamicUpdate in JPA?

@DynamicUpdate is a class-level annotation that can be applied to a JPA entity. It ensures that Hibernate uses only the modified columns in the SQL statement that it generates for the update of an entity. In this article, we'll take a look at the @DynamicUpdate annotation, with the help of a Spring Data JPA example.

Can we use JPA with R2DBC?

JPA cannot deal with reactive repositories such as provided by Spring Data R2DBC. This means you will have to do more things manually when using R2DBC. There are other reactive drivers around such as for example Quarkus Reactive Postgres client (which uses Vert.

What is spring JPA Hibernate DDL Auto?

spring. jpa. hibernate. ddl-auto (enum) is a Hibernate feature that controls the behavior in a more fine-grained way.


1 Answers

First of all I want to explain why @DynamicUpdate is not working for you. So I should notice how @DynamicUpdate works:

The @DynamicUpdate annotation is used to specify that the UPDATE SQL statement should be generated whenever an entity is modified. By default, Hibernate uses a cached UPDATE statement that sets all table columns. When the entity is annotated with the @DynamicUpdate annotation, the PreparedStatement is going to include only the columns whose values have been changed.(more details)

For example assume that User has a property called name.

So if for the first time you saved user with a defined name, now you are passing null as the value @DynamicUpdate will assume it as a change and trying to update name to null.

First solution:

As the first solution, if you want @DynamicUpdate works, first you should fill all other User properties with old values, then you can save it.

Pros: The generated SQL query just updates the property you want.

Cons: Hibernate has to generate the corresponding SQL string each time and there is thus a performance cost on the Hibernate side.

Second solution:

You can update User with custom query:

@Modifying
@Query("UPDATE User SET name=(:name) WHERE id=(:id)")
public void updateName(@Param("name")String name, @Param("id")Long id);

Third solution:

As the last solution I can suggest you to use updatable = false. This will fill the property on the very first moment the entity inserted.

  @Column(name = "create_date", nullable = false, updatable = false)
    private Instant createDate;
like image 162
Mohsen Avatar answered Oct 06 '22 11:10

Mohsen