Open yagotlima opened 4 years ago
Any update here?
Any update here?
Hi. Unfortunately no. I managed to fix that project by managing concurrency in Java itself. My Stack Overflow post was deleted for some reason. I can paste it here if you want more details.
Thanks, @yagotlima. Please paste it here and share the link as well.
Thanks, @yagotlima. Please paste it here and share the link as well.
My original Stack Overflow question was:
I have a Grails application using mongoDB that runs a long piece of code that updates a domain class at the end. Since this piece of code runs concurrently I'm gatting a lot of OptimisticLockingException
s.
To avoid that I decide to do as following:
def method(Vehicle vehicle) {
// long read only code using vehicle's properties
synchronyzed(lock) {
vehicle.refresh()
vehicle.property = newValue
vehicle.save()
}
}
Unfortunatelly the refresh
method is not implemented on GORM for MongoDB and throws java.lang.UnsupportedOperationException: Refresh not supported by codec entity persistence engine
.
I also tried the following:
def method(Vehicle vehicle) {
// long read only code using vehicle's properties
synchronyzed(lock) {
vehicle = Vehicle.get(vehicle.id)
vehicle.property = newValue
vehicle.save()
}
}
But looks like there is some sort of session that returns the same object like Hibernate's L1 cache would.
Is there a way to refresh this instance?
PS: I'm aware I can switch the class to stateless mode but that would require a huge refactor and stateful mode is just better for my use case except for this piece of code.
So far, the need of refresh()
was only coming in our integration tests. For that, we are doing this-
Vehicle vehicleInstance // some existing instance
Vehicle.withNewSession {
vehicleInstance = Vehicle.get(vehicleInstance.id)
}
We further made this DRY in our base abstract test file by adding a method-
GormEntity refreshInstance(GormEntity instance) {
// Flushing to get persist it to DB immediately
instance.save(flush: true)
UserOrAnyDomain.withNewSession {
return instance.class.get(instance.id)
}
}
and then calling directly-
Vehicle vehicleInstance // some existing instance
vehicleInstance = refreshInstance(vehicleInstance)
I think Vehicle.withNewSession { vehicleInstance = Vehicle.get(vehicleInstance.id) }
is exactly what I was looking for back then. Even though we managed to work around this problem, it's great to know how to deal with it moving forward. Thank you.
Thanks, @yagotlima. I would like to keep this issue open so that the GORM team can implement it natively.
@sagrawal31 sorry for that
I'm creating this issue after failing to find a solution from Stackoverflow.
Since the
refresh
method is not implemented on Gorm for Mongo and the methodget(id)
would return the same cached instance, is it possible to refresh a domain class instance from the database?