Java 冬眠“;提供的id类型错误,预期为Long,Get class DelayedPostInsertIdentifier“;例外
简而言之: 当我尝试将新的(未保存的)实体添加到已保存父实体的一对多集合中时,在对父实体调用Merge之后,我得到以下异常: 为com.test.Child类提供了错误类型的id。预期: 类java.lang.Long,获得类 org.hibernate.action.internal.DelayedPostInsertIdentifier 我发现了一张代表同一问题的票: 它被拒绝了,对我的问题没有多大帮助 有人面对过这个问题吗? 有人能指出问题的根源和可能的解决办法吗 问题详情: 我有两门课: 公共类父扩展BaseModel实现可序列化{ 私人长id; 私人儿童; } 我正在尝试执行以下代码:Java 冬眠“;提供的id类型错误,预期为Long,Get class DelayedPostInsertIdentifier“;例外,java,hibernate,one-to-many,hibernate-onetomany,Java,Hibernate,One To Many,Hibernate Onetomany,简而言之: 当我尝试将新的(未保存的)实体添加到已保存父实体的一对多集合中时,在对父实体调用Merge之后,我得到以下异常: 为com.test.Child类提供了错误类型的id。预期: 类java.lang.Long,获得类 org.hibernate.action.internal.DelayedPostInsertIdentifier 我发现了一张代表同一问题的票: 它被拒绝了,对我的问题没有多大帮助 有人面对过这个问题吗? 有人能指出问题的根源和可能的解决办法吗 问题详情: 我有两门课:
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);
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会在某个时刻尝试加载“第二个”子级
- 但是它还没有被插入,并且免职被提出
- 我也遇到了这个问题。请注意,您的saveOrUpdate方法没有启动事务。解决方案是启动事务,并确保在调用session.update或session.saveOrUpdate后提交事务
按如下方式更新您的saveOrUpdate方法:
public void saveOrUpdate(T obj) {
Session session = getSession();
Transaction tx = null;
try {
tx = session.beginTransaction();
BaseModel model = (BaseModel) obj;
if (model.isNew()) {
T merged = (T)session.merge(obj);
session.update(merged);
} else {
session.saveOrUpdate(obj);
}
tx.commit();
} catch (Exception ex) {
tx.rollback();
}
}
这给了我一个解决问题的提示,您的saveOrUpdate方法验证了丢失的事务 我在使用Hibernate 4.2.15和Spring时遇到了同样的问题。按照@arjaynacion的建议,向执行保存的方法添加@Transactional注释解决了该问题:
@Transactional
@NotNull
protected S save(@NotNull S entity)
{
return getDao().save(entity);
}
我们在那里不使用事务,因为我们在更高的级别上使用:我们确实需要在一个事务中更新和创建多个不同类型的实体。有些时候,我们只是不将事务用于不重要的实体(发生异常的地方)。也许,这是问题的根源。我们需要创建一些机制,只在需要时创建事务。@Dmitrieisemenov,当你说你在更高级别上使用事务时,你是说你在使用某种事务管理框架(例如Spring-Spring tx)?您能告诉我为什么不创建事务就调用saveOrUpdate或update方法吗?
public void saveOrUpdate(T obj) {
Session session = getSession();
Transaction tx = null;
try {
tx = session.beginTransaction();
BaseModel model = (BaseModel) obj;
if (model.isNew()) {
T merged = (T)session.merge(obj);
session.update(merged);
} else {
session.saveOrUpdate(obj);
}
tx.commit();
} catch (Exception ex) {
tx.rollback();
}
}
@Transactional
@NotNull
protected S save(@NotNull S entity)
{
return getDao().save(entity);
}