![](/img/trans.png)
[英]Spring Data Mongodb and CrudRepository save(): dropped fields from document if not in POJO model
[英]Spring Data CrudRepository only returns changed fields when calling save()
我使用Spring数据(版本1.13.9.RELEASE),并有一个CrudRepository
称为myRepository
。 我正在调用myRepository.save(myObject)
,以覆盖数据库中myObject
的现有实例,并且将myObject
某些字段指定为null
。
例如:
{
"prop1": "val1",
"prop2": null,
"prop3": "val3"
}
当我调用myRepository.save(myObject)
并读取返回值时,我设置为null
的myObject
所有字段都将返回null
(在本示例中为prop2
)。
但是, prop2
在数据库中的null
在调用save()
之后不为null
-在我调用save()
之前,它仍然具有先前的值。
这实际上是我在特定情况下想要的行为(在调用myRepository.save()
时忽略null
值),但是我希望save()
的返回值反映操作后数据库中的实际情况,而不是只返回指定为null
的更新字段和将字段设置为null
或它们的默认值(对于布尔值,例如返回false
。
这是CrudRepository
的save()
行为的预期行为吗?
要了解该问题,您需要了解一些有关Hibernate Object Lifecycle的知识。
休眠对象生命周期包括以下状态:1.临时状态2.持久状态3.分离状态等
当创建一个新对象时,它处于过渡状态,并且Hibernate无法检测到处于过渡状态的对象。
当您调用save()
saveOrUpdate()
,对象将从瞬态转换为持久状态,现在Hibernate将开始跟踪对该对象所做的所有更改(但该对象尚未写入db)。
因此,在您的情况下,由于对象不是处于持久状态,因此休眠无法识别它,并且将触发(最有可能) insert
查询。 但是,如果对象已经处于持久状态,则休眠将知道某些字段已修改,因此将触发update
查询。
这就是为什么要让休眠触发update
查询时,需要确保对象处于持久状态。
这意味着事务尚未完成,所有更改仅在缓存内。 要强制更新,您可以调用entityManager.flush()
或将所需的所有逻辑移到另一个服务或管理器的单独公共方法中,并将其注释为@Transactional
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.