简体   繁体   中英

Spring Data CrudRepository only returns changed fields when calling save()

I'm using Spring Data (version 1.13.9.RELEASE) and have a CrudRepository called myRepository . I'm calling myRepository.save(myObject) , to overwrite an existing instance of myObject in the database, and I'm specifying some fields of myObject as null .

For example:

{
    "prop1": "val1",
    "prop2": null,
    "prop3": "val3"
}

When I call myRepository.save(myObject) and read the return value, all of the fields of myObject that I set as null are returned as null (so prop2 in this example).

However, the value for prop2 in the database is NOT null after calling save() - it still has the previous value before I called save() .

This is actually the behavior that I want in this particular situation (to ignore null values when calling myRepository.save() ), but I'd like the return value of save() to reflect what is actually in the database after the operation, rather than only returning the updated fields and setting fields specified as null to null or their default value (such as false in the case of a boolean.

Is this the expected behavior of CrudRepository 's save() behavior?

To understand the problem you need to understand a little bit about Hibernate Object Lifecycle.

The Hibernate Object Lifecycle consist of these states : 1. Transient State 2. Persistent State 3. Detached State etc

When you create a new object, its in the transient state and Hibernate has no means of detection of objects present/created in the transient state.

When you call save() saveOrUpdate() then the object moves from transient state to persistent state and now Hibernate will start keeping a track of all the changes made to the object (but the object is not yet written in the db).

So in your case, since the object is not in the persistent state, hibernate fails to recognise it and will fire (most likely) an insert query. However, if the object was already in the persistent state, hibernate would have known that some fields have modified and hence will fire an update query.

That is why you need to make sure the object is in persistent state if you want hibernate to fire an update query.

It means that the transaction is not complete yet and all the changes are only within the cache. To force updating you may call entityManager.flush() or move all the logic that you need into a separate public method of another Service or Manager and annotate it as @Transactional

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM