我正在使用grails 1.3.7和zkoss,并且我的域模型如下所示,我在 session 1中加载Person实体,并通过UI对其进行更改。
在 session 2中单击保存时,我要保存实体。
因此,从我的作曲者/ Controller 中,我调用了一个服务方法(transactional),然后调用了person.save()。当我看到被触发的sql查询时,我看到了一个试图检索雇员对象的查询。
之后,保存被触发并引发非唯一对象异常
异常(exception)
org.hibernate.NonUniqueObjectException: a different object with the same identifier value was already associated with the session: [com.nthdimenzion.domain.Employee#2]
询问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] ...... }
这种行为正确吗?
最佳答案
您必须在Employee
映射中指定empId
是主键-这可能是NonUniqueObjectException
的唯一原因。
SQL查询必须来自对empId
字段的唯一约束。
为什么不使用Grails / Hibernate隐式id
,您是否在使用具有特定映射的旧数据库?
编辑我不明白为什么唯一约束会导致NonUniqueObjectException
-您可以在没有约束的情况下尝试吗?
如果问题仍然存在,则必须在同一 session 中两次保存对象-不知道它如何发生,也许是通过merge()
-在较早的 session 中添加一个Employee
来实现的。
SQL查询是由唯一性约束引起的,这是正确的。
关于hibernate - gorm save方法导致选择查询触发,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5987968/