Grails:坚持

时间:2016-11-15 06:19:11

标签: java hibernate session grails

我在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而不是刷新吗?

感谢。

1 个答案:

答案 0 :(得分:0)

您的所有业务逻辑都必须位于事务性服务中。默认情况下,grails中的所有服务都是事务性的。请注意注释为@Transactional@NotTransactional

如果要管理控制器中的数据(不推荐),则应将代码包含在事务中。允许hibernate来管理事务,而不是使用flush来打破它。

所有更改都在事务完成后提交。

请记住,您还可以使用刷新方法,该方法从底层数据库重新读取给定实例的状态。

domainInstance.refresh()