#hibernate #grails #grails-orm
#переход в спящий режим #grails #grails-orm
Вопрос:
Я использую grails 1.3.7 и zkoss, и моя модель домена такая, как показано ниже, я загружаю объект Person в сеансе 1 и вношу в него изменения через пользовательский интерфейс.
При нажатии кнопки save в сеансе 2 я хочу сохранить объект.
Итак, из моего композитора / контроллера я вызываю сервисный метод (транзакционный), а затем выполняю person.save(), когда я вижу, что запускаются sql-запросы, я вижу запрос, который пытается извлечь объект employee.
После чего выполняется сохранение и генерируется исключение nonuniqueobjectexception
org.переход в спящий режим.Исключение NonUniqueObjectException: другой объект с тем же значением идентификатора уже был связан с сеансом: [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]
......
}
Правильно ли это поведение?
Ответ №1:
Вы, должно быть, указали в Employee
сопоставлении, который empId
является первичным ключом — вероятно, это единственная причина для NonUniqueObjectException
.
SQL-запрос должен исходить из уникального ограничения на empId
поле.
Почему бы не использовать Grails / Hibernate неявно id
, вы используете устаревшую базу данных с определенным отображением?
редактировать Я не понимаю, почему это может вызвать ограничение уникальности NonUniqueObjectException
— не могли бы вы, пожалуйста, попробовать это без ограничения?
Если проблема остается, вы, должно быть, дважды сохранили объект из одного и того же сеанса — понятия не имею, как это может произойти, возможно, merge()
вставив Employee
из предыдущего сеанса.
SQL-запрос вызван ограничением уникальности, и это правильно.
Комментарии:
1. Нет, я этого не делал, я дважды проверял это! Таблица создания моего сотрудника выглядит так, как показано ниже Create TABLE
employee
(id
АВТО_ИНКРЕМЕНТ BIGINT(20) НЕ РАВЕН НУЛЮ,version
BIGINT(20) НЕ РАВЕН НУЛЮ,emp_id
VARCHAR (255) НЕ РАВЕН НУЛЮ,2. Есть ли у
Employee
классаstatic mapping
поле илиstatic constraints
? Или вы используете аннотации Hibernate или XML config?3. он имеет как статическое отображение, так и статические ограничения, обновил мой вопрос, чтобы показать статические сопоставления и ограничения
4. Я очень удивлен, если я удалю ограничение уникальности, оно будет работать отлично!! почему ограничение уникальности приводит к запуску запросов select?
5. просто потому, что его нужно проверить. Перед выдачей
INSERT
вам необходимо проверить, не нарушаете ли вы какие-либо ограничения. Интересно, почему бы вместо этого не перевести процесс Hibernate в режим гибернацииSqlException
/NonUniqueObjectException
, если существует ограничение уникальности базы данных — но так оно и работает.