Объект JPA, измененный отражением, не объединенный менеджером объекта - PullRequest
0 голосов
/ 06 июня 2019

Мне нужно проверить, отличается ли моя действительная сущность от старой.

Я использую отражение, потому что мой метод должен быть стандартизирован.

Для каждого столбца я обновляю значение тогда и только тогда, когда оно не равно нулю (поскольку я читаю его из 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)

Если я сделаю такие изменения, запрос ОБНОВЛЕНИЕ не будет выполнен.

Если я меняю значение обычным образом oldobject.setValue(newValue), запрос выполняется и запись обновляется.

Почему менеджер сущностей не выполняет запрос UPDATE, если я изменяю значение с помощью отражения?

Ответы [ 2 ]

2 голосов
/ 06 июня 2019

Просто найдите хорошую информацию о таком поведении в this :

По умолчанию при использовании weaving / agent EclipseLink использует отслеживание изменений атрибутов для выявления изменений.Это не будет обнаруживать изменения, сделанные с помощью доступа к отражающему полю (хотя доступ к методу в порядке).

Вы можете изменить значение по умолчанию, используя аннотацию @ChangeTracking на deferred, которая будет обнаруживать изменения, сделанные с помощью отражения.т.е. @ChangeTracking (ChangeTrackingType.DEFERRED)

Вы также можете отключить переплетение или отслеживание изменений в файле persistence.xml, используя "eclipselink.weaving.changetracking" = "false"

Итак, есть пара решений, которые можно попробовать:

  1. Использовать рефлексивный метод доступа
  2. Изменить ChangeTracking на отложенный или даже отключить его
  3. Отключить ткачество
0 голосов
/ 06 июня 2019

Спасибо @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().

Теперь это работает

...