我正在使用Spring Data(1.13.9.RELEASE版本),并且有一个名为CrudRepository
的{{1}}。我正在调用myRepository
,以覆盖数据库中myRepository.save(myObject)
的现有实例,并将myObject
的某些字段指定为myObject
。
例如:
null
当我调用{
"prop1": "val1",
"prop2": null,
"prop3": "val3"
}
并读取返回值时,我设置为myRepository.save(myObject)
的{{1}}的所有字段都将返回为myObject
(所以{{1} })。
但是,在调用null
之后,数据库中null
的值不是prop2
-在调用prop2
之前它仍然具有先前的值。
这实际上是我在特定情况下想要的行为(在调用null
时忽略save()
值),但是我希望save()
的返回值反映出什么实际上是在操作后存储在数据库中,而不是仅将指定为null
的更新字段和设置字段返回到myRepository.save()
或它们的默认值(对于布尔值,例如save()
这是null
的{{1}}行为的预期行为吗?
答案 0 :(得分:0)
要了解该问题,您需要了解一些有关Hibernate Object Lifecycle的知识。
休眠对象生命周期包含以下状态: 1.瞬态 2.持久状态 3.分离状态等
当创建一个新对象时,它处于过渡状态,并且Hibernate无法检测到存在/创建的处于过渡状态的对象。
当您调用save()
saveOrUpdate()
时,对象将从瞬态转换为持久状态,现在,Hibernate将开始跟踪对该对象所做的所有更改(但该对象尚未写入)在数据库中)。
因此,在您的情况下,由于对象不是处于持久状态,因此休眠无法识别它,并且将(最有可能)触发insert
查询。但是,如果对象已经处于持久状态,则休眠将知道某些字段已被修改,因此将触发update
查询。
这就是为什么要让休眠触发update
查询时,需要确保对象处于持久状态。
答案 1 :(得分:0)
这意味着事务尚未完成,所有更改仅在缓存内。要强制更新,您可以调用entityManager.flush()
或将所需的所有逻辑移到另一个Service或Manager的单独的公共方法中,并将其注释为@Transactional