0

我需要检查我的实际实体是否与旧实体不同。

我使用反射是因为我的方法必须标准化。

对于每一列,当且仅当它不为空时,我才更新值(因为我从 CSV 读取它并且可能未指定列)。

for(Field column : fields){
   column.setAccessible(true);
   Object newValue = column.get(myObject);
   if( newValue != null && !newValue.equals(column.get(oldObject))){
      column.set(oldObject, newValue);
   }
}

this.entitymanager.merge(oldObject)

如果我进行这样的更改,则不会完成任何 UPDATE 查询。

如果我以正常方式更改值,oldobject.setValue(newValue)则查询完成并更新记录。

如果我通过反射更改值,为什么实体管理器不执行 UPDATE 查询?

4

2 回答 2

2

只需在此处找到有关此类行为的一些有用信息

默认情况下,使用编织/代理 EclipseLink 使用属性更改跟踪来检测更改。这不会检测通过反射字段访问所做的更改(尽管方法访问是可以的)。

您可以使用 @ChangeTracking 注释将默认值更改为 deferred,这将检测通过反射所做的更改。即@ChangeTracking(ChangeTrackingType.DEFERRED)

您还可以使用“eclipselink.weaving.changetracking”="false" 在persistence.xml 中禁用编织或更改跟踪编织

所以有几个解决方案可以尝试:

  1. 使用反射方法访问
  2. 将 ChangeTracking 更改为延迟甚至禁用它
  3. 禁用编织
于 2019-06-06T09:22:06.753 回答
0

感谢@Ken Chan 的回答,我更正了使用getter 和setter 的方法。

for(Field column : columns){
   Method mSet = myclass.getMethod("set"+ StringUtils.capitalize(column.getName()), column.getType());
   Method mGet = myclass.getMethod("get"+ StringUtils.capitalize(column.getName()));
   Object newValue = mGet.invoke(articolo);
   if( newValue != null && !newValue.equals(mGet.invoke(old))){
        mSet.invoke(old, newValue);
   }
 }

我必须注意方法的名称。如果实体有属性description,也必须有getDescription()and setDescription()

现在它可以工作了

于 2019-06-06T10:34:13.320 回答