【问题标题】:Hibernate batching operation not working as expected休眠批处理操作未按预期工作
【发布时间】:2011-05-19 12:13:05
【问题描述】:

我有一个包含以下字段的 Person 类-

id、hashedId、描述

id是序列生成的主键,hashedId不为空。

我执行以下操作:

  1. session.saveOrUpdate(person)
  2. person.setHashedId(hash(person.getId()))

ID 是在数据库中自动生成的。当我这样做时,我不应该期望只有 2 个语句

  1. 选择获取下一个序列ID(人物ID)
  2. Insert 以插入人员记录?

但是,它正在尝试在第 1 步之后(当然是在最终事务提交期间)使用 null hashedId 插入 - 我得到一个违反约束的错误 - HashedId 不能为 null。

【问题讨论】:

    标签: database hibernate postgresql orm


    【解决方案1】:

    HashedId 字段是从 ID 派生的,对吧?我假设基于廉价的功能?那么在这种情况下,您真的需要将该字段保留在数据库中吗?您是否直接在查询中使用它? 你不能让 getHashedId() 方法总是返回 hash(this.id) 吗?这样您就不会在数据库中拥有 hashedId 字段并且您不必管理它 - 因为它只是根据 id 推断出来的。

    希望这会有所帮助。

    【讨论】:

      【解决方案2】:

      当您调用Session.save() 或类似名称时,Hibernate 将立即生成 ID 并执行插入操作,而不是简单地将其排队等待稍后保存。因此,元素在插入之前分配其 ID 是没有间隙的。对于“身份”ID生成策略,无论如何都完全不可能将它们分开......

      根据我的经验,处理这种情况的最安全和最简单的方法是使用拦截器(或者可能是 EventListener?)来捕获正在插入且未设置 hashedId 属性的实体,并在保存之前生成它。这有点令人不快,但恕我直言,这比将 ID 生成拉到应用程序代码中要好。

      这是一个示例,其中我生成了新 Ticket 实体的“引用”属性(使用拦截器):

      public boolean onSave(Object entity, Serializable id, Object[] state, String[] propertyNames,
          Type[] types) {
          boolean changed = super.onSave(entity, id, state, propertyNames, types);
      
          if (entity instanceof Ticket) {
              for (int i = 0; i < propertyNames.length; i++) {
                  if (propertyNames[i].equals("reference") && state[i] == null) {
                      state[i] = generateTicketReference((Integer) id);
                      changed = true;
                  }
              }
          }
      
          return changed;
      }
      

      【讨论】:

        【解决方案3】:

        Hibernate 正在做正确的事 :-) 请参阅 http://docs.jboss.org/hibernate/core/3.3/reference/en/html/mapping.html#mapping-declaration-id ,“5.1.4.4. 标识列和序列”部分

        这是因为 Hibernate 不知道 ID 是否由 DB 生成。并且 ID 并没有真正分配给记录,只是因为您调用了一个序列。因此,您应该让 Hibernate 保存记录并检索记录的实际 ID,或者您应该使用 Hibernate 生成的 ID(如 hilo)(或自己生成,生成器类型为“已分配”)。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2011-08-06
          • 2015-11-02
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2020-12-17
          • 1970-01-01
          相关资源
          最近更新 更多