问题
I have 2 domain class with a many to many relationship. When I delete the entity that belongs to the other, I have to remove the relation before in order to avoid a foreign key error.
I would like to put this code in the beforeDelete event, but I obtain a problem with optimistc locking. This is the code of the domain classes:
class POI {
static belongsTo = [Registration];
static hasMany = [registrations: Registration]
def beforeDelete = {
def poiId = this.id
POI.withNewSession { session ->
def regs = Registration.withCriteria{
pois{
idEq(this.id)
}
}
def poi = POI.get(poiId)
if(poi != null && regs.size() > 0){
regs.each{
it.removeFromPois(poi)
}
poi.save(flush: true)
}
}
}
}
}
class Registration {
static hasMany=[pois: POI];
}
So the relation between POI and Registration are deleted, in the beforeDelete when I call delete on an poi, but then when it tries to execute effectively the delete, I have the following error:
optimistic locking failed; nested exception is org.hibernate.StaleObjectStateException:
Row was updated or deleted by another transaction (or unsaved-value mapping was
incorrect): [ambienticwebsite.POI#22]
Anyone has an idea how to solve this problem by using tthe beforeDelete?
回答1:
In most cases with GORM, dealing with a many-to-many relationship without manually creating a class to represent the join table creates a lot of headaches.
An example of this is the Spring Security Core Plugin's PersonAuthority class.
An example of many to many where deleting either end deletes the join entry as well:
class POI {
def beforeDelete() {
RegistrationPOI.withNewSession {
def rps = RegistrationPOI.findByPOI(this)
rps.each { it.delete(flush: true) } // flush is necessary
}
}
/* example convenience method to get directly
* from a POI to the associated Registrations */
Collection<Registration> getRegistrations() {
RegistrationPOI.findByPOI(this)
}
}
class Registration {
def beforeDelete() {
RegistrationPOI.withNewSession {
def rps = RegistrationPOI.findByRegistration(this)
rps.each { it.delete(flush: true) } // flush is necessary
}
}
}
class RegistrationPOI {
Registration registration
POI poi
}
来源:https://stackoverflow.com/questions/16986285/grails-beforedelete-with-many-to-many-relation