gorm save method causing a select query to fire

2019-02-26 00:40发布

问题:

I am using grails 1.3.7 and zkoss and my domain model is as below, I load the Person entity in session 1 and make changes to it through the UI.

The on press of save in session 2 I want to save the entity.

So from my composer/controller I call a service method(transactional) and then do person.save(), When i see the sql queries being fired I see a query which tries to retrieve the employee object.

After which the save is fired and throws a nonuniqueobjectexception Exception

org.hibernate.NonUniqueObjectException: a different object with the same identifier value was already associated with the session: [com.nthdimenzion.domain.Employee#2]

Query

Hibernate: select this_.id as id7_0_, this_.version as version7_0_, this_.emp_id as emp4_7_0_, this_.person_id as person5_7_0_ from person_role this_ where this_.class='com.nthdimenzion.domain.Employee' and this_.emp_id=?

class PersonService {
static transactional = true
def savePerson(Person person) {
    person = person.save();
}

}

class Person extends Party{

String firstName;
String middleName;  
static hasMany = [ personRoles : PersonRole ] -- lazy loaded

.... }

class PersonRole {
public static enum ROLETYPES{
    EMPLOYEE,AUTHOR
};
public boolean hasRoleType (ROLETYPES roleType){
    return false;
}
static transients = ['ROLETYPES']
static constraints = {
}
 }



class Employee extends PersonRole{
def empRoleType = [ROLETYPES.EMPLOYEE]
String empId
    static belongsTo = [person:Person]
 static transients = ['empRoleType', 'uid']
static constraints = {
    books(nullable:true)
    empId(unique:true)
}
static hasMany = [books:Book]
static mapping = { books cascade:"all" }
static belongsTo = [person:Person]
  ......
}

Is this behavior correct ?

回答1:

You must have specified in Employee mapping that empId is the primary key - that's probably the only reason for NonUniqueObjectException.

The SQL query must come from an unique constraint on empId field.

Why not using Grails'/Hibernate implicit id, are you using a legacy database with a specific mapping?

edit I don't see why would unique constraint cause NonUniqueObjectException - can you please try it without the constraint?

If the problem remains, you must have saved the object twice from the same session - no idea how it can happen, maybe by merge()-ing an Employee from earlier session.

The SQL query is caused by uniqueness constraint and it's the right thing.