У меня есть эти два классаIllegalStateException с Hibernate 4 и ManyToOne каскадирование
MyItem Объект:
@Entity
public class MyItem implements Serializable {
@Id
private Integer id;
@ManyToOne(cascade = {CascadeType.PERSIST, CascadeType.MERGE})
private Component defaultComponent;
@ManyToOne(cascade = {CascadeType.PERSIST, CascadeType.MERGE})
private Component masterComponent;
//default constructor, getter, setter, equals and hashCode
}
Component Object:
@Entity
public class Component implements Serializable {
@Id
private String name;
//again, default constructor, getter, setter, equals and hashCode
}
И я Тринг сохраняются те с следующий код:
public class Test {
public static void main(String[] args) {
Component c1 = new Component();
c1.setName("comp");
Component c2 = new Component();
c2.setName("comp");
System.out.println(c1.equals(c2)); //TRUE
MyItem item = new MyItem();
item.setId(5);
item.setDefaultComponent(c1);
item.setMasterComponent(c2);
ItemDAO itemDAO = new ItemDAO();
itemDAO.merge(item);
}
}
Хотя это прекрасно работает с Hibernate 3.6, Hibernate 4.1.3 бросает
Exception in thread "main" java.lang.IllegalStateException: An entity copy was already assigned to a different entity.
at org.hibernate.event.internal.EventCache.put(EventCache.java:184)
at org.hibernate.event.internal.DefaultMergeEventListener.entityIsDetached(DefaultMergeEventListener.java:285)
at org.hibernate.event.internal.DefaultMergeEventListener.onMerge(DefaultMergeEventListener.java:151)
at org.hibernate.internal.SessionImpl.fireMerge(SessionImpl.java:914)
at org.hibernate.internal.SessionImpl.merge(SessionImpl.java:896)
at org.hibernate.engine.spi.CascadingAction$6.cascade(CascadingAction.java:288)
at org.hibernate.engine.internal.Cascade.cascadeToOne(Cascade.java:380)
at org.hibernate.engine.internal.Cascade.cascadeAssociation(Cascade.java:323)
at org.hibernate.engine.internal.Cascade.cascadeProperty(Cascade.java:208)
at org.hibernate.engine.internal.Cascade.cascade(Cascade.java:165)
at org.hibernate.event.internal.AbstractSaveEventListener.cascadeBeforeSave(AbstractSaveEventListener.java:423)
at org.hibernate.event.internal.DefaultMergeEventListener.entityIsTransient(DefaultMergeEventListener.java:213)
at org.hibernate.event.internal.DefaultMergeEventListener.entityIsDetached(DefaultMergeEventListener.java:282)
at org.hibernate.event.internal.DefaultMergeEventListener.onMerge(DefaultMergeEventListener.java:151)
at org.hibernate.event.internal.DefaultMergeEventListener.onMerge(DefaultMergeEventListener.java:76)
at org.hibernate.internal.SessionImpl.fireMerge(SessionImpl.java:904)
at org.hibernate.internal.SessionImpl.merge(SessionImpl.java:888)
at org.hibernate.internal.SessionImpl.merge(SessionImpl.java:892)
at org.hibernate.ejb.AbstractEntityManagerImpl.merge(AbstractEntityManagerImpl.java:874)
at sandbox.h4bug.Test$GenericDAO.merge(Test.java:79)
at sandbox.h4bug.Test.main(Test.java:25)
Database Бэкэнд h2 (но то же самое происходит с HSQLDB или дерби). Что я делаю не так?
К сожалению, оба идентификатора не сгенерированы в базе данных, а заданы явно. –
К сожалению, я имел в виду класс Component. вы даете им тот же самый идентификатор? –
Да, это идея. Оба компонента имеют одинаковый идентификатор и равны (см. Выше оператор равенства). Итак, каскад должен позаботиться об этом, верно? Вы даже можете попытаться использовать ту же ссылку (например, c1) для обеих переменных (defaultComponent и masterComponent), так как они в любом случае равны. –