java Hibernate“提供的id类型错误,预期为Long,Get class DelayedPostInsertIdentifier”异常
简而言之:
当我尝试将新的(未保存的)实体添加到已保存父实体的一对多集合中时,在对父实体调用Merge之后,我得到以下异常:
Provided id of the wrong type for class com.test.Child. Expected: class java.lang.Long, got class org.hibernate.action.internal.DelayedPostInsertIdentifier
我找到了一张代表同一问题的票:https://hibernate.atlassian.net/browse/HHH-2382 它被拒绝了,对我的问题没有多大帮助
有人面临过这个问题吗? 有人能指出问题的根源和可能的解决办法吗
问题详情:
我有两门课: 公共类父扩展BaseModel实现可序列化{ 私人长id; 私人儿童; }
public class Child extends BaseModel implements Serializable {
private long id;
private String value;
}
我正在尝试执行以下代码:
Parent parent = new Parent();
parent.setChildren(new HashSet<Child>());
Child child = new Child();
child.setValue("First");
parent.getChildren().add(child);
parent = daoFacade.save(parent);
child = new Child();
child.setValue("Second");
parent.getChildren().add(child);
parent = daoFacade.save(parent);
第二次调用save方法后,我得到以下异常:
org.hibernate.TypeMismatchException: Provided id of the wrong type for class com.text.Child. Expected: class java.lang.Long, got class org.hibernate.action.internal.DelayedPostInsertIdentifier at org.hibernate.event.internal.DefaultLoadEventListener.onLoad(DefaultLoadEventListener.java:134) at org.hibernate.internal.SessionImpl.fireLoad(SessionImpl.java:1092) at org.hibernate.internal.SessionImpl.internalLoad(SessionImpl.java:1019) at org.hibernate.type.EntityType.resolveIdentifier(EntityType.java:648) at org.hibernate.type.EntityType.resolve(EntityType.java:468) at org.hibernate.type.EntityType.replace(EntityType.java:325) at org.hibernate.type.CollectionType.replaceElements(CollectionType.java:517) at org.hibernate.type.CollectionType.replace(CollectionType.java:667) at org.hibernate.type.TypeHelper.replace(TypeHelper.java:177) at org.hibernate.event.internal.DefaultMergeEventListener.copyValues(DefaultMergeEventListener.java:372) at org.hibernate.event.internal.DefaultMergeEventListener.entityIsPersistent(DefaultMergeEventListener.java:184) at org.hibernate.event.internal.DefaultMergeEventListener.onMerge(DefaultMergeEventListener.java:157) at org.hibernate.event.internal.DefaultMergeEventListener.onMerge(DefaultMergeEventListener.java:76) at org.hibernate.internal.SessionImpl.fireMerge(SessionImpl.java:914) at org.hibernate.internal.SessionImpl.merge(SessionImpl.java:898) at org.hibernate.internal.SessionImpl.merge(SessionImpl.java:902) at com.test.DAOFacade.saveObject(DAOFacade.java:273) at com.test.Test.testSaving(MemcachedTest.java:99)
道门面。保存方法如下所示:
public void saveOrUpdate(T obj) {
Session session = getSession();
BaseModel model = (BaseModel) obj;
if (model.isNew()) {
T merged = (T)session.merge(obj);
session.update(merged);
} else {
session.saveOrUpdate(obj);
}
session.flush();
}
Hibernate映射包括:
<class name="Parent" table="PARENT">
<id name="id" column="id" unsaved-value="0">
<generator class="native"/>
</id>
<set name="children" inverse="false" lazy="false" cascade="all">
<cache usage="read-write" />
<key column="LINK_ID"/>
<one-to-many class="Child"/>
</set>
</class>
<class name="Child" table="CHILD">
<cache usage="read-write" />
<id name="id" column="id" unsaved-value="0">
<generator class="native"/>
</id>
<property name="value" type="string" column="VALUE" not-null="true" lazy="false"/>
</class>
我已经调试了几个小时,Hibernate中的所有进程似乎都正常运行,但实际上它导致了以下问题:
- 在合并期间,在迭代字段期间,未保存的“第二个”子项 找到了李>
- “第二个”子项被标记为插入,插入查询被准备好并被放入QueryQueue李>
- 继续合并过程,Hibernate会在某个时刻尝试加载“第二个”子级
- 但是它还没有被插入,并且免职被提出李>
# 1 楼答案
我也遇到了这个问题。请注意,您的saveOrUpdate方法没有启动事务。解决方法是启动一个事务,并确保在调用会话后提交事务。更新或会话。保存或更新
按如下方式更新saveOrUpdate方法:
这个thread给了我一个解决问题的提示,您的saveOrUpdate方法验证了丢失的事务
# 2 楼答案
我在使用Hibernate 4.2.15和Spring时也遇到了同样的问题。按照@arjaynacion的建议,向执行保存的方法添加@Transactional注释解决了这个问题: