Я использую Hibernate 3, и у меня возникает особая проблема при сохранении нового объекта, который связан с существующим отдельным объектом.Самый простой способ объяснить это с помощью примеров кода.У меня есть две сущности, FooEntity и BarEntity, из которых BarEntity может быть связан со многими FooEntity:
@Entity
public class FooEntity implements Foo{
@Id
private Long id;
@ManyToOne(targetEntity = BarEntity.class)
@JoinColumn(name = "bar_id", referencedColumnName = "id")
@Cascade(value={CascadeType.ALL})
private Bar bar;
}
@Entity
public class BarEntity implements Bar{
@Id
private Long id;
@OneToMany(mappedBy = "bar", targetEntity = FooEntity.class)
private Set<Foo> foos;
}
Foo и Bar являются интерфейсами, которые свободно определяют геттеры для различных полей.Существуют соответствующие классы FooImpl и BarImpl, которые по сути являются просто объектами сущности без аннотаций.
Я пытаюсь создать новый экземпляр FooImpl и сохранить его после установки нескольких полей.В новом экземпляре Foo его член 'bar' будет установлен на существующий Bar (среда выполнения - BarEntity) из базы данных (получена с помощью session.get (..)).После того, как FooImpl установит все свои свойства, Apache Dozer используется для сопоставления между объектом 'domain' FooImpl и Entity FooEntity.Dozer делает в фоновом режиме создание нового FooEntity и установку всех соответствующих полей.BarEntity также клонируется с помощью инстанцирования и устанавливает член 'bar' в FooEntity.
После этого, передавая новый объект FooEntity для сохранения.Это выдает исключение:
org.hibernate.PersistentObjectException: detached entity passed to persist: com.company.entity.BarEntity
Ниже приведен код, который выполняет шаги
FooImpl foo = new FooImpl();
//returns at runtime a persistent BarEntity through session.get()
Bar bar = BarService.getBar(1L);
foo.setBar(bar);
...
//This constructs a new instance of FooEntity, with a member 'bar' which itself is a new instance that is detached)
FooEntity entityToPersist = dozerMapper.map(foo, FooEntity.class);
...
session.persist(entityToPersist);
Мне удалось решить эту проблему, удалив или изменив аннотацию @Cascade,но это ограничивает будущее использование, скажем, добавления нового Foo с уже прикрепленным новым Bar.Есть ли какое-то решение здесь, которого я пропускаю?Я был бы удивлен, если бы эта проблема не была решена где-то прежде, либо путем изменения того, как Dozer Maps отображает дочерние элементы Foo, либо как Hibernate реагирует на отдельную дочернюю сущность.