【发布时间】:2013-07-13 21:06:15
【问题描述】:
大家好,
我目前正在尝试了解,我的编码和实体模型有什么问题 我使用休眠 4.2 进行 CRUD 操作,仅使用 Generic DAO 模式和带有级联 ALL 和 orphanRemoval=true 的注释实体。 我的 DayPlan 实体与 DayPlanElement 弱实体具有 OneToMany 关系。 DayPlanElement 保存在 java.util.Set 中。每个DayPlanElement都有一个属性“order”。
DayPlan 还与实体 Person 具有 OneToMany 关系。实体 Person 保存到 java.util.List 中。
DayPlanElement 与 DayPlanElementEntry 弱实体具有 OneToMany 关系。 java.util.Set 用于保存。 Person 实体也与 DayPlanElementEntry 弱实体的 OneToMany 关系。 java.util.Set 用于保存。 DayPlan、DayPlanElement 和 Person 实体具有由我的应用程序管理的 ID 作为字符串。 DayPlanElementEntry 弱实体有一个复合 Id:DayPlanElementEntryId 用 EmbeddedId 注解,包含 parentPersonId 和 dayPlanElementId。它
换句话说,想象一下,存在一张表,代表一天的计划。列是从 0 到 24 的小时数。行是必须从日计划进行操作的人员。每列都是 DayPlanElement 实体。每行都是 Person 实体。每个单元格都是 DayPlanElementEntry 实体。
如果我只是向表中添加新元素(也是 Persons)并删除它(也从 List 中删除它,然后调用 DayPlanDAO.merge(dayPlan) - 我希望在级联和 orphanRemoval 上) - 我没有问题。
仅当我尝试对给定的 Persons 重新排序(仅删除 java.util.List 中的操作)和调用 DayPlanDAO.merge(dayPlan) - 将引发以下异常:
Caused by: java.lang.IllegalStateException:
Error occurred while storing entity
[DayPlanElementEntry [getDayPlanMode()=NONE, getCompositeId()=DayPlanElementEntryId [parentPersonId=874c8eac-8796-478d-a4d5-dd011f7d6a4b, dayPlanElementId=ab683a25-633e-419e-89b6-4aef7829d4f6], hashCode=-2039940039]].
An entity copy
[org.hw.domain.DayPlanElementEntry#DayPlanElementEntryId [parentPersonId=874c8eac-8796-478d-a4d5-dd011f7d6a4b, dayPlanElementId=ab683a25-633e-419e-89b6-4aef7829d4f6]]
was already assigned to a different entity
[org.hw.domain.DayPlanElementEntry#DayPlanElementEntryId [parentPersonId=874c8eac-8796-478d-a4d5-dd011f7d6a4b, dayPlanElementId=ab683a25-633e-419e-89b6-4aef7829d4f6]].
at org.hibernate.event.internal.EventCache.put(EventCache.java:192)
at org.hibernate.event.internal.DefaultMergeEventListener.entityIsDetached(DefaultMergeEventListener.java:285)
at org.hibernate.event.internal.DefaultMergeEventListener.onMerge(DefaultMergeEventListener.java:151)
我调试EventCache,寻找问题解决方案,只检查实现的equals()和hashCode()方法——没有成功:-(( 请注意,我将 ID 用于 equals() 方法。例如 DayPlanElementEntry 的复合 id。该 id 由 hashCode() 使用。我只是不明白错误消息,三次将输出相同的属性 - id!
我找到了用于事件缓存的test class,但现在我不明白以下用例测试:
@Test
public void testCopyAssociatedWith2ExistingEntities() {
session.getTransaction().begin();
Simple entity1 = new Simple( 1 );
session.persist( entity1 );
Simple copy1 = new Simple( 1 );
cache.put(entity1, copy1);
Simple entity2 = new Simple( 2 );
session.persist( entity2 );
Simple copy2 = new Simple( 2 );
cache.put( entity2, copy2 );
session.flush();
try {
cache.put( entity1, copy2 );
fail( "should have thrown IllegalStateException");
}
catch( IllegalStateException ex ) {
// expected
assertTrue( ex.getMessage().startsWith( "Error occurred while storing entity [org.hibernate.event.internal.EventCacheTest$Simple#1]." ) );
}
session.getTransaction().rollback();
}
....
@Entity
private static class Simple {
@Id
private int value;
public Simple(int value) {
this.value = value;
}
public int getValue() {
return value;
}
public void setValue(int value) {
this.value = value;
}
}
我们有 Id=1 的简单实体 entity1,然后我们将其持久化。然后我们创建简单实体 copy1 并将其作为值放入事件缓存中。作为键使用的持久化实体*1*。 然后我们创建一个 Id=2 的 Simple entity*2* ,持久化它,然后创建 id 为 2 的 copy*2* 实体并将其作为值放入事件缓存中。使用持久化的 entity2 作为关键。 为什么这种情况是错误的,为什么必须抛出 IllegalStateException?
感谢您的帮助!
【问题讨论】:
-
同样的问题!请,如果您找到解决方案 - 发布它