繁体   English   中英

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

[英]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)并读取返回值时,我设置为nullmyObject所有字段都将返回null (在本示例中为prop2 )。

但是, prop2在数据库中的null在调用save()之后不为null -在我调用save()之前,它仍然具有先前的值。

这实际上是我在特定情况下想要的行为(在调用myRepository.save()时忽略null值),但是我希望save()的返回值反映操作后数据库中的实际情况,而不是只返回指定为null的更新字段和将字段设置为null或它们的默认值(对于布尔值,例如返回false

这是CrudRepositorysave()行为的预期行为吗?

要了解该问题,您需要了解一些有关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.

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