我在Grails面临一个奇怪的问题。当我在更改和保存域的值后进行findBy
调用时,即使将值保持到数据库,我仍然会获得旧值。我可以在表格中看到值已更改。
我的代码是这样的:
Car car = Car.findByCarId(carId)
car.modelName = "some_model_name"
car.save() // Not flushing here
Tire tire = Tire.findByIdAndCarId(tireId,carId)
tire.manufacturer = "some_manufacturer"
tire.save()
Light light = Light.findByIdAndCarId(lightId,carId)
light.manufacturer = "some_manufacturer"
light.save()
Mirror mirror = Mirror.findByIdAndCarId(mirrorId,carId)
mirror.manufacturer = "some_manufacturer"
mirror.save()
我的域名也有一些一对多关联。我们这样说:
class Car {
String modelName
static hasMany = [tires : Tire, mirrors : Mirror, lights : Light]
}
完成这些更改后,当我为Car
域进行数据库调用时,我仍然会获得较旧的值:
Car car = Car.findById(carId)
println car.modelName // This gives older value
我知道这是因为值尚未持久保存到数据库中。我想知道在上面的代码中是否使用car.save(flush: true)
,是否会导致collection was not processed by flush()
错误?但是,即使将值保留到数据库之后,我也会获取较旧的值。 (例如,当我在很长一段时间后进行上述查询时)我可以看到我的表中的值已更改,但是当我执行上述查询时,它会为我提供旧值。 Hibernate会自动缓存此查询吗?我使用了上面的查询很多次。
当我使用withNewSession
时,它会检索新值:
Car car
Car.withNewSession {
car = Car.findById(carId,[readOnly : true])
}
println car.modelName // Gives new value
我想知道每次都是如何给出新值,因为我没有冲洗当前的会话。相反,我只使用新的Hibernate会话。 readOnly
命令是否刷新当前会话?上面的代码对我来说很好。保存时我应该使用withNewSession
而不是刷新吗?
感谢。
答案 0 :(得分:0)
您的所有业务逻辑都必须位于事务性服务中。默认情况下,grails中的所有服务都是事务性的。请注意注释为@Transactional
或@NotTransactional
如果要管理控制器中的数据(不推荐),则应将代码包含在事务中。允许hibernate来管理事务,而不是使用flush来打破它。
所有更改都在事务完成后提交。
请记住,您还可以使用刷新方法,该方法从底层数据库重新读取给定实例的状态。
domainInstance.refresh()