Объект JPA, измененный отражением, не объединенный менеджером объекта
Мне нужно проверить, отличается ли моя действительная сущность от старой.
Я использую отражение, потому что мой метод должен быть стандартизирован.
Для каждого столбца я обновляю значение тогда и только тогда, когда оно не равно нулю (потому что я читаю его из 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, если я изменяю значение с помощью отражения?
2 ответа
Просто найдите хорошую информацию о таком поведении в этом:
По умолчанию при использовании weaving/agent EclipseLink использует отслеживание изменений атрибутов для обнаружения изменений. Это не обнаружит изменения, сделанные через доступ к отражающему полю (хотя доступ к методу в порядке).
Вы можете изменить значение по умолчанию с помощью аннотации @ChangeTracking на deferred, которая будет обнаруживать изменения, сделанные с помощью отражения. т.е. @ChangeTracking(ChangeTrackingType.DEFERRED)
Вы также можете отключить переплетение или отслеживание изменений в файле persistence.xml, используя "eclipselink.weaving.changetracking"="false"
Итак, есть несколько решений, которые можно попробовать:
- Использовать рефлексивный метод доступа
- Измените ChangeTracking на отложенный или даже отключите его
- Отключить ткачество
Спасибо @Ken Chan ответу, я исправляю метод, используя геттеры и сеттеры.
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()
а также setDescription()
,
Теперь работает