有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

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会在某个时刻尝试加载“第二个”子级
  • 但是它还没有被插入,并且免职被提出

共 (2) 个答案

  1. # 1 楼答案

    我也遇到了这个问题。请注意,您的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();
       }
    
    }
    

    这个thread给了我一个解决问题的提示,您的saveOrUpdate方法验证了丢失的事务

  2. # 2 楼答案

    我在使用Hibernate 4.2.15和Spring时也遇到了同样的问题。按照@arjaynacion的建议,向执行保存的方法添加@Transactional注释解决了这个问题:

    @Transactional
     @NotNull
     protected S save(@NotNull S entity)
     {
        return getDao().save(entity);
     }