gpt4 book ai didi

java - Hibernate 拦截器 - 为什么在 onSave 之后调用 onFlushDirty?

转载 作者:塔克拉玛干 更新时间:2023-11-03 03:21:33 29 4
gpt4 key购买 nike

计划

我正在使用 Hibernate 为一个小项目实现 createDate 和 lastUpdate 时间戳。我使用 EmptyInterceptor 并根据我发现的建议解决方案重载提供的方法 here .除非有一点细节,否则该解决方案工作正常。我想添加一个列来指示对象是否已经更新。我知道我可以通过简单地比较两个创建和更新的时间戳是否存在差异来实现这一点,但我需要让这个字段指示有一个更新。

我使用在存储新对象时调用的 onSave 方法将 wasUpdated 值设置为“N”,表示没有更新。在 onFlushDirty() 方法中,我将此值设置为“Y”。

问题

当我创建并持久化一个新对象时,我会指出 createDate 和 lastUpdate 字段具有相同的日期,但 wasUpdated 字段设置为“N”,因为没有更新。我只在我的代码中使用 session.save(),没有 session.update() 也没有 session.saveOrUpdate()。 Hibernate 的日志表明实际上有一个 Update,它将 wasUpdated 值设置为 'Y'。

此更新的来源是什么?在哪里触发?

对象初始化和持久化

我在 hibernate.cfg.xml 中禁用了自动提交。

<property name="hibernate.connection.autocommit">false</property>

这是我创建对象的方式:

ExampleObject ex = new ExampleObject();
ex.setValue("TestStringValue");
this.session = HibernateUtil.getSessionFactory().openSession();
this.session.beginTransaction();
this.session.save(ex);
this.session.getTransaction().commit();
this.session.close();

拦截器

@Override
public boolean onSave(Object entity, Serializable id, Object[] state,
String[] propertyNames, Type[] types) {


if (entity instanceof TimeStamped) {

Date insertDate = new Date();
int indexOfCreateDateColumn = ArrayUtils.indexOf(propertyNames, "createdDate");
int indexOfUpdatedDateColumn = ArrayUtils.indexOf(propertyNames, "lastUpdatedDate");
int indexOfWasUpdated = ArrayUtils.indexOf(propertyNames, "wasUpdated");

state[indexOfCreateDateColumn] =insertDate;
state[indexOfUpdatedDateColumn] =insertDate;
state[indexOfWasUpdated] ='N';

return true;
}
return false;
}

第二种方法是设置 lastUpdatedDate 并将 wasUpdated 字段设置为“Y”。

@Override
public boolean onFlushDirty(Object entity, Serializable id, Object[] currentState,
Object[] previousState, String[] propertyNames, Type[] types) {

if (entity instanceof TimeStamped) {

int indexOfLastUpdate = ArrayUtils.indexOf(propertyNames, "lastUpdatedDate");
int indexOfWasUpdated = ArrayUtils.indexOf(propertyNames, "wasUpdated");

currentState[indexOfLastUpdate] = new Date();
currentState[indexOfWasUpdated] ='Y';


return true;
}
return false;
}

hibernate 工具

我将此配置用于 session 。

public class HibernateUtil {
private static SessionFactory sessionFactory;
private static ServiceRegistry serviceRegistry;

static {
try {

Configuration configuration = new Configuration().setInterceptor(new TimeStampInterceptor());
configuration.configure();

serviceRegistry = new StandardServiceRegistryBuilder().applySettings(configuration.getProperties()).build();
sessionFactory = configuration.buildSessionFactory(serviceRegistry);


} catch (HibernateException he) {
System.err.println("Error creating Session: " + he);
throw new ExceptionInInitializerError(he);
}
}

public static SessionFactory getSessionFactory() {
return sessionFactory;
}
}

版本

我使用 Maven 和 Java 1.7.0_40。

    <!--. Hibernate -->
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>4.3.4.Final</version>
</dependency>

最佳答案

onFlushDirty() 方法的 JavaDoc 有如下语句:

Called when an object is detected to be dirty, during a flush.

因此,无论对象是由于 update() 调用而变脏还是由于 save() 调用而变脏,都没有区别。因此 onFlushDirty() 方法将在 session 刷新时在每个持久对象上调用。 session 刷新可以由 session.flush() 显式启动,或者在某些情况下当 Hibernate 需要它时(在您的情况下 - 在事务提交之前)隐式启动。

在您的情况下,wasUpdated 属性将始终使用“Y”值保存:首先将调用 onSave() 方法,当 session 刷新时 onFlushDirty () 方法将在同一个实体上被调用。

要解决 onFlushDirty() 方法中的问题,您应该检查实体是否已更新。如果我没记错的话,当实体插入到表中(保存新的)时,先前的状态为空。建议像这样实现 onFlushDirty():

@Override
public boolean onFlushDirty(Object entity, Serializable id, Object[] currentState,
Object[] previousState, String[] propertyNames, Type[] types) {

if (entity instanceof TimeStamped && previousState!=null) {

int indexOfLastUpdate = ArrayUtils.indexOf(propertyNames, "lastUpdatedDate");
int indexOfWasUpdated = ArrayUtils.indexOf(propertyNames, "wasUpdated");

currentState[indexOfLastUpdate] = new Date();
currentState[indexOfWasUpdated] ='Y';


return true;
}
return false;
}

关于java - Hibernate 拦截器 - 为什么在 onSave 之后调用 onFlushDirty?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25155868/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com