Hibernate 踩坑日记

来源:互联网 发布:oracle查找重复数据 编辑:程序博客网 时间:2024/04/30 04:09

## 环境

Spring4 + hibernate5 + jpa

坑一

描述

打算使用es, 所以给hibernate 配置了拦截器, 如下

    <bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">        <property name="persistenceUnitName" value="persistenceUnit"/>        <property name="persistenceUnitManager" ref="persistenceUnitManager"/>        <property name="dataSource" ref="dataSource" />        <property name="jpaVendorAdapter">            <bean id="jpaVendorAdapter" class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">                <property name="database" value="MYSQL"/>            </bean>        </property>        <property name="jpaDialect">            <bean class="org.springframework.orm.jpa.vendor.HibernateJpaDialect"/>        </property>        <property name="jpaPropertyMap">            <map>                <entry key="hibernate.ejb.interceptor.session_scoped">                    <value>per.posse.tool.interceptor.HibernateSessionInterceptor</value>                </entry>            </map>        </property>    </bean>

HibernateSessionInterceptor 实现了 org.hibernate.Interceptor 接口

问题

RETRIEVE, CREATE, CREATE, 全无问题, 但是UPDATE 操作毫无反应, 数据不更新, 也不报错, 也不打印update的sql.

原因及解决

HibernateSessionInterceptor 具体实现还没写, 编译器默认生成Interceptor接口的实现方法, 有个方法叫findDirty(), 编译器默认实现空方法是

    @Override    public int[] findDirty(Object entity, Serializable id, Object[] currentState, Object[] previousState,            String[] propertyNames, Type[] types) {        return new int[0];    }

查看描述

Called from flush(). The return value determines whether the entity is updated


  • an array of property indices - the entity is dirty
  • an empty array - the entity is not dirtinte

也就是hibernate 在执行 flush() 操作的时候, 会调用这个方法, 返回值决定实体是否被update返回值有值, 实体被改写, 需要更新持久化上下文, 返回值是空数组, hibernate不认为实体被改动, 不执行更新操作,返回null, 则由hibernate 默认的dirty-checking 机制判断是否需要更新, 它有自己的一套DirtyCheckEventListener, DirtyCheckEvent机制.

所以编译器给我默认返回new int[0], hibernate 认为实体不需要更新, 所以就没有执行update, 所以把返回先改成null ,再做update操作, 打印sql, 数据库更新.
OK.

原创粉丝点击