简体   繁体   English

Spring Data CrudRepository仅在调用save()时返回更改的字段

[英]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 . 我使用Spring数据(版本1.13.9.RELEASE),并有一个CrudRepository称为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 . 我正在调用myRepository.save(myObject) ,以覆盖数据库中myObject的现有实例,并且将myObject某些字段指定为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). 当我调用myRepository.save(myObject)并读取返回值时,我设置为nullmyObject所有字段都将返回null (在本示例中为prop2 )。

However, the value for prop2 in the database is NOT null after calling save() - it still has the previous value before I called save() . 但是, prop2在数据库中的null在调用save()之后不为null -在我调用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. 这实际上是我在特定情况下想要的行为(在调用myRepository.save()时忽略null值),但是我希望save()的返回值反映操作后数据库中的实际情况,而不是只返回指定为null的更新字段和将字段设置为null或它们的默认值(对于布尔值,例如返回false

Is this the expected behavior of CrudRepository 's save() behavior? 这是CrudRepositorysave()行为的预期行为吗?

To understand the problem you need to understand a little bit about Hibernate Object Lifecycle. 要了解该问题,您需要了解一些有关Hibernate Object Lifecycle的知识。

The Hibernate Object Lifecycle consist of these states : 1. Transient State 2. Persistent State 3. Detached State etc 休眠对象生命周期包括以下状态:1.临时状态2.持久状态3.分离状态等

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. 当创建一个新对象时,它处于过渡状态,并且Hibernate无法检测到处于过渡状态的对象。

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). 当您调用save() saveOrUpdate() ,对象将从瞬态转换为持久状态,现在Hibernate将开始跟踪对该对象所做的所有更改(但该对象尚未写入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. 因此,在您的情况下,由于对象不是处于持久状态,因此休眠无法识别它,并且将触发(最有可能) insert查询。 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. 但是,如果对象已经处于持久状态,则休眠将知道某些字段已修改,因此将触发update查询。

That is why you need to make sure the object is in persistent state if you want hibernate to fire an update query. 这就是为什么要让休眠触发update查询时,需要确保对象处于持久状态。

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 要强制更新,您可以调用entityManager.flush()或将所需的所有逻辑移到另一个服务或管理器的单独公共方法中,并将其注释为@Transactional

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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