当前位置: 首页 > 知识库问答 >
问题:

Hibernate拦截器,修改当前状态在onSave结果SQL更新

丁弘新
2023-03-14

假设我有两个类Foo和Bar。Foo有一个多对一的关联到Bar,映射如下:

<many-to-one name="bar" class="Bar" lazy="false" fetch="join" >
    <column name="BAR_ID" sql-type="INTEGER" />
</many-to-one>

我已经创建了一个自定义拦截器,该拦截器从EmptyInterceptor扩展并覆盖onSave方法,如下所示:

public boolean onSave(Object entity, Serializable id, Object[] state,
        String[] propertyNames, Type[] types) {
    boolean modified = false;

    if(entity instanceof Foo) {
        Bar bar = new Bar();

        //do some initialization stuff to bar

        for(int i = 0; i < propertyNames.length; i++) {
             if("bar".equals(propertyNames[i])) {
                 state[i] = bar;
                 modified = true;
                 break;
             } 
        }

        //This code essentially gets the current hibernate session and calls save on
        //the passed object.
        BarDAO barDao = BarDAO.INSTANCE;
        barDAO.save(bar);
    }

    return modified;
} 

问题在于,尽管对bar执行SQL insert语句,但对实体对象执行SQL update语句,实体对象是一个Foo,在插入之前已被修改。这将导致以下Hibernate异常。

最后一个原因:批量更新从更新[0]返回了意外的行数;实际行数:0;预期:1

如果不保存bar对象,则会按预期执行SQL insert语句。

对可能出现的问题有什么见解吗?

提前谢谢。

共有1个答案

晋越彬
2023-03-14

我认为您需要在拦截器中的onFlushDirty方法中更新当前状态数组。

有一个类似的问题,因为我正在修改onLoad和onFlushDirty方法中的对象。问题是hibernate认为对象的前一个状态是由onLoad方法产生的,update语句试图使用这些值来查找db表中的行。可能是相同的问题,因为您正在修改onSave方法中的状态。

 类似资料:
  • 我正在使用Hibernate为一个小项目实现createDate和lastUpdate时间戳。我使用一个EmptyInterceptor,并根据我在这里找到的建议解决方案重载提供的方法。除非有一点细节,否则这个解决方案很好用。我想添加一列,指示对象是否已经更新。我知道我可以通过简单地比较两个创建和更新的时间戳是否有差异来实现这一点,但是我需要有这个字段来指示有一个更新。 我使用onSave方法,在

  • 问题内容: 我尝试了一些来自hibernate 4.0拦截器的 代码,该代码为使用会话级拦截器提供了以下代码: 但是,我同时检查了hibernate-core 4.0源代码和onliehibernate 4.0 java- doc ,该类没有方法,但是hibernate 3.6 java- doc确实具有此方法。 有人知道该方法移到哪里吗?如果已弃用,为什么文档仍将其保留在教程文档中?在4.0中如

  • 我的应用程序由spring@transaction和hibernate组成。我正在尝试使用hibernate拦截器。我把拦截器注册为 实际的拦截器扩展了EmptyInterceptor,我正在重写onSave()方法。 问题是调用了interceptor onSave()方法,但在此之后,实际实体不会插入到数据库中。

  • You can enable changing of locales by adding the LocaleChangeInterceptor to one of the handler mappings (see [Section 21.4, "Handler mappings"](mvc.html the request and change the locale. It calls set

  • 问题内容: 我正在尝试构建一个脚本,该脚本将充当本机对象的代理/包装器,使我能够对其进行拦截,修改responseText并返回到原始的onreadystatechange事件。 如果应用正在尝试接收的数据在本地存储中已经存在,则上下文将中止并将本地存储的数据传递回应用成功/失败回调方法。假设我无法控制应用程序现有的AJAX回调方法。 我最初尝试过以下想法。 但是正如我现在确定的那样,respon

  • 问题内容: 我有带有不同(HTML和JSON)结果类型的Struts2操作。他们使用通用拦截器。 如果需要拦截请求,如何根据给定的操作结果类型返回结果? 例如,我转发到JSP页面。如果操作是JSON类型,我想转发JSON错误。 问题答案: 我有带有不同(HTML和JSON)结果类型的Struts2操作。他们使用通用拦截器。如果需要拦截请求,如何根据给定的动作结果类型返回结果? 例如,我的Actio