Java 冬眠“;提供的id类型错误,预期为Long,Get class DelayedPostInsertIdentifier“;例外

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 我发现了一张代表同一问题的票: 它被拒绝了,对我的问题没有多大帮助 有人面对过这个问题吗? 有人能指出问题的根源和可能的解决办法吗 问题详情: 我有两门课:

简而言之:

当我尝试将新的(未保存的)实体添加到已保存父实体的一对多集合中时,在对父实体调用Merge之后,我得到以下异常:

为com.test.Child类提供了错误类型的id。预期: 类java.lang.Long,获得类 org.hibernate.action.internal.DelayedPostInsertIdentifier

我发现了一张代表同一问题的票: 它被拒绝了,对我的问题没有多大帮助

有人面对过这个问题吗? 有人能指出问题的根源和可能的解决办法吗

问题详情:

我有两门课: 公共类父扩展BaseModel实现可序列化{ 私人长id; 私人儿童; }

我正在尝试执行以下代码:

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);
       }