Обновление составного объекта завершается неудачно - PullRequest
2 голосов
/ 27 августа 2009

У меня есть объект Person, имеющий состав с объектом Entity

@ManyToOne(fetch = FetchType.EAGER, cascade =
{ CascadeType.PERSIST, CascadeType.MERGE })
@Cascade(
{org.hibernate.annotations.CascadeType.SAVE_UPDATE })
public Location getLocation()
{
    return location;
}

И объект местоположения имеет имя в качестве идентификатора

@Id
public String getName()
{
    return name;
}

Я получаю следующее исключение, когда местоположение Person изменяется с L1 на L2 в Spring MVC форме, где этот объект Person является modelAttribute для формы.

org.springframework.orm.hibernate3.HibernateSystemException: идентификатор экземпляра com.x.y.z.Расположение было изменено с L2 на L1; вложенным исключением является org.hibernate.HibernateException: идентификатор экземпляра com.x.y.z.Расположение было изменено с L2 на L1

Ответы [ 3 ]

3 голосов
/ 27 августа 2009

Ты путаешь Композиция с Ассоциация .

То, что вы нанесли на карту, является ассоциацией; Композиция в Hibernate (JPA) отображается с помощью аннотаций @Embeddable / @Embedded. Ассоциации - это отношения между отдельными объектами; они обычно связаны через идентификаторы сущностей (внешние ключи в базе данных).

В вашем конкретном случае сущность Person указывает на сущность Location, что означает, что в таблице PERSONS таблица имеет внешний ключ LOCATION_ID (имена могут отличаться) на таблицу LOCATIONS. То, что вы пытаетесь сделать, это обновить этот ключ на Location конце, что недопустимо, потому что оно разорвало бы связь Hibernate (другой конец все еще содержит предыдущее значение ключа внутри).

Первичные ключи обычно должны быть суррогатными и не подлежать обновлению с самого начала; если вам нужно «обновить» его, вам придется либо отсоединить Location от Person, обновить Location и снова присвоить его Person ИЛИ создать новый экземпляр Location и назначить его своему Person.

Все это говорит о том, что если вы действительно пытаетесь смоделировать отношения композиции, вам нужно заменить @ManyToOne на @Embedded и соответственно изменить схему таблицы. Вот ссылка на Документация Hibernate Annotations для компонентов сопоставления .

Кроме того, указание типов каскадов в двух отдельных аннотациях (расширение JPA и расширение Hibernate) не очень хорошая вещь. Если вам действительно нужно расширение Hibernate (которое в данном случае вам не нужно), просто используйте его и оставьте атрибут cascade в аннотациях JPA пустым.

0 голосов
/ 15 июля 2014

В вашем атрибуте атрибута сущности Location тип был изменен в классе вашей модели . Пожалуйста, укажите идентификаторы идентификатора и идентификатора атрибута сопоставления совпадают . Убедитесь, что атрибут id Возвращает типы функций получения и установки.

0 голосов
/ 31 августа 2009

Я сделал то же самое в автономном приложении. Вещь работает. Я думаю, что это должно быть проблема с @modelAttribute.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...