1. Overview

When we use Spring Data JPA with Hibernate, we can use the additional features of Hibernate as well. @DynamicUpdate is one such feature.

@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.

2. JPA @Entity

When an application starts, Hibernate generates the SQL statements for CRUD operations of all the entities. These SQL statements are generated once and are cached, in memory, to improve the performance.

The generated SQL update statement includes all the columns of an entity. In case we update an entity, the values of the modified columns are passed to the SQL update statement. For the columns that are not updated, Hibernate uses their existing values for the update.

Let’s try to understand this with an example. First, let’s consider a JPA entity named Account:

@Entity
public class Account {

    @Id
    private int id;

    @Column
    private String name;

    @Column
    private String type;

    @Column
    private boolean active;

    // Getters and Setters
}

Next, let’s write a JPA repository for the Account entity:

@Repository
public interface AccountRepository extends JpaRepository<Account, Integer> {
}

Now, we’ll use the AccountRepository to update the name field of an Account object:

Optional<Account> account = accountRepository.findById(ACCOUNT_ID);
if(account.isPresent()){
    account.get().setName("Test Account");
    accountRepository.save(account.get());
}

After we execute this update, we can verify the generated SQL statement. The generated SQL statement will include all the columns of Account:

update Account set active=?, name=?, type=? where id=?

3. JPA @Entity with @DynamicUpdate

We’ve seen that even though we’ve modified the name field only, Hibernate has included all the columns in the SQL statement.

Now, let’s add the @DynamicUpdate annotation to the Account entity:

@Entity
@DynamicUpdate
public class Account {
    // Existing data and methods
}

Next, let’s run the same update code we used in the previous section. We can see that the SQL generated by Hibernate, in this case, includes only the name column:

update Account set name=? where id=?

So, what happens when we use @DynamicUpdate on an entity?

Actually, when we use @DynamicUpdate on an entity, Hibernate does not use the cached SQL statement for the update. Instead, it will generate a SQL statement each time we update the entity. This generated SQL includes only the changed columns.

In order to find out the changed columns, Hibernate needs to track the state of the current entity. So, when we change any field of an entity, it compares the current and the modified states of the entity.

This means that @DynamicUpdate has a performance overhead associated with it. Therefore, we should only use it when it’s actually required.

Certainly, there are a few scenarios where we should use this annotation — for example, if an entity represents a table that has a large number of columns and only a few of these columns are required to be updated frequently. Also, when we use version-less optimistic locking, we need to use @DynamicUpdate.

4. Conclusion

In this tutorial, we’ve looked into the @DynamicUpdate annotation of Hibernate. We’ve used an example of Spring Data JPA to see @DynamicUpdate in action. Also, we’ve discussed when we should use this feature and when we should not.

As always, the complete code examples used in this tutorial are available over on GitHub.