How to prevent Hibernate from updating column values as null in a PUT web request when the entity uses @DynamicUpdate


#1

Hi,

I am trying to update a single property using PUT method. I am using DynamicUpdate annotation in Entity. I am facing the following issue. Consider I have 5 columns in a table and all values are inserted, In PUT request if I pass only one value as JSON Request, it is updating the remaining 4 columns with null… How to avoid/configure DynamicUpdate to not to update if any null values are being passed in PUT request.

Note: Updatable as false cannot be included in the entity since all fields can be passed in PUT request at different instances.


#2

Unlike a POST, where you can reconstruct the entire entity snapshot when using PUT, you need to specify what property you want to update.

Now, in a @Transactional method, you need to:

  1. Fetch the entity: Post post = entityManager.find(Post.class, postId);

  2. Set the entity property using the value you submitted via PUT: post.setTitle(title);

If you want to make it dynamic, you can use Java Reflection to set the entity property by matching the provied proeprty name.

When the current transaction is committed, a flush will occur and propagate the entity property change to the database.

That’s it.


#3

Thanks Vlad. My entity is of complex type as it contains relationship like @OneToMany which again contains @OneToMany relationship.

Other than manual setting up of the fields/using bean mappers is there anyway to notify spring not to update the values to null if the values are already existing in DB. In my case comparing each field/setting it manually will be a hectic task.


#4

Other than manual setting up of the fields/using bean mappers is there any way to notify spring not to update the values to null if the values are already existing in DB.

You should retain the previously fetched entity that you sued to render the UI. Afterward, in the PUT request, you can let Spring change the entity based on the provided PUT request.

Afterward, you just use merge, assuming that you are using CascadeType.MERGE for child associations. This way, you no longer have to manually locate and set each prperty that gets modified.