我已按照文档中的描述设置了Spring Data JPA审核。我认为它配置正确,因为在插入时,我已正确填写所有4个字段(created
,createdBy
,modified
,modifiedBy
。
现在有趣的部分。在修改实体时,一切似乎都运行良好。我通过所有Spring审计类调试到AuditingHandler.java
这一行:
LOGGER.debug("Touched {} - Last modification at {} by {}", new Object[] { target, defaultedNow, defaultedAuditor });
看起来完全没问题。目标已正确设置修改后的字段,我无法在数据库中看到任何问题但,这两个字段不会更新。 (值仍然是创建日期和用户)。所以不知何故它不会被保存。当然所有其他字段都会更新,包括JPA版本字段。所以除了修改过的*字段之外的一切。
我很无能为力。谁能帮我进一步调试呢?
我在1.9.0中使用Spring-Data-JPA,在持久性后端中使用Spring 4.2.1和OpenJPA。
更新
我认为我确定了问题,但OpenJPA或Spring-Data JPA中存在一个错误。
Spring-Data的以下类BeanWrapper.java运行此代码:
/*
* (non-Javadoc)
* @see org.springframework.data.mapping.PersistentPropertyAccessor#setProperty(org.springframework.data.mapping.PersistentProperty, java.lang.Object)
*/
public void setProperty(PersistentProperty<?> property, Object value) {
Assert.notNull(property, "PersistentProperty must not be null!");
try {
if (!property.usePropertyAccess()) {
ReflectionUtils.makeAccessible(property.getField());
ReflectionUtils.setField(property.getField(), bean, value);
return;
}
Method setter = property.getSetter();
if (property.usePropertyAccess() && setter != null) {
ReflectionUtils.makeAccessible(setter);
ReflectionUtils.invokeMethod(setter, bean, value);
}
} catch (IllegalStateException e) {
throw new MappingException("Could not set object property!", e);
}
}
JpaPersistentPropertyImpl(property)将usePropertyAccess属性设置为false,从而直接通过反射更改修改的字段,但不会在OpenJPA中将标记为脏的属性。在调试器中将值修改为true时,强制使用setter(),一切正常。
所以某处是OpenJPA&lt; - &gt;的问题。 Spring Data交互。似乎OpenJPA不喜欢反射属性更改并且坚持使用setter()。
有没有办法让这个usePropertyAccess属性变为true?
结论
每一次旅程都需要结束。我发现在我修改的* / created *字段上使用@AccessType(AccessType.Type.PROPERTY)
可以解决问题。我不太确定当前默认 - &gt; AccessType.Type.Field
是Spring-Data中最明智的...至少不适用于OpenJPA。 IMO很难找到非经验丰富的JPA / Spring开发人员。也许文档中的注释会有所帮助。在我的生活中,我从未使用过AccessType
属性,而且我在OpenJPA中使用Spring已经有一段时间......