【发布时间】:2015-02-20 12:43:50
【问题描述】:
问题: 为什么从不调用MyInterceptor#onFlushDirty?
我在 xml 配置中扩展 AbstractEntityManagerFactoryBean,例如
<bean id="myEntityManagerFactory" parent="abstractEntityManagerFactoryBean" abstract="true">
<property name="entityInterceptor">
<bean class="xxxx.MyInterceptor"/>
</property>
</bean>
<bean id="abstractEntityManagerFactoryBean" class="xxxx.MyEntityManagerFactoryBean"/>
MyEntityManagerFactoryBean
public class MyEntityManagerFactoryBean extends AbstractEntityManagerFactoryBean implements LoadTimeWeaverAware {
private Interceptor entityInterceptor;
public Interceptor getEntityInterceptor() {
return entityInterceptor;
}
public void setEntityInterceptor(Interceptor interceptor) {
entityInterceptor = interceptor;
}
}
我的拦截器:
public class MyInterceptor extends EmptyInterceptor {
public MyInterceptor() {
System.out.println("init"); // Works well
}
// PROBLEM - is never called
@Override
public boolean onFlushDirty(Object entity,
Serializable id,
Object[] currentState,
Object[] previousState,
String[] propertyNames,
Type[] types) {
if (entity instanceof File) {
.....
}
return false;
}
}
更新:[解释为什么自定义脏策略看起来不像我的方式]
每次我更改 Folder 实体中的某些内容时,我都想更新 modified 时间戳,但 folderPosition 除外。同时folderPosition 应该是持久的而不是瞬态的(意味着导致实体变脏)。
由于我使用 Spring Transactional 和 Hibernate 模板,因此存在一些细微差别:
1) 我无法在每个 setter 结束时更新修改后的时间戳,例如:
public void setXXX(XXX xxx) {
//PROBLEM: Hibernate templates collect object via setters,
//means simple get query will cause multiple 'modified' timestamp updates
this.xxx = xxx;
this.modified = new Date();
}
2) 我不能手动调用 setModified,因为它有大约 25 个字段,并且每个字段的 setXXX 分散在整个应用程序中。而且我无权进行重构。
@Entity
public class Folder {
/**
* GOAL: Changing of each of these fields except 'folderPosition' should cause
* 'modified' timestamp update
*/
private long id;
private String name;
private Date created;
private Date modified;
private Integer folderLocation;
@PreUpdate
public void preUpdate() {
//PROBLEM : change modified even if only location field has been changed!
//PROBLEM: need to know which fields have been updated!
modified = new Date();
}
....
}
【问题讨论】:
-
你能用这个 spring 配置显示你想填充的自定义 EntityManager 类吗
-
@Vihar 我有点进步。但是我的拦截器仍然无法按预期工作。你可以看看我更新的问题吗?
-
@Vihar 你的意思是我现在需要删除构造函数吗?
-
@Vihar 之前的错误是由于
getInterceptor/setInterceptorMyEntityManagerFactoryBean缺席引起的 -
离题,但始终建议在复杂方法上添加
@Override。只是为了确保您不会因为拼写错误而意外声明新方法。
标签: java spring hibernate jpa orm