узнать различия между двумя java beans для отслеживания версий

например, у меня есть java bean / entity с 100 полями (унаследовано или нет, в данном случае оно не имеет значения). После операций обновления – в транзакции я хочу определить, какие поля изменены для отслеживания обновлений, таких как CVS. Каков самый простой способ сделать это? Любое предложение Framework? Должен ли я сделать два экземпляра этого объекта и перебрать все поля и сопоставить значения полей? Каким образом наилучший равный метод проявляется в таких ситуациях? Следующие equals () кажутся очень неудобными:

return (field1.equals(o.field1)) && (field2.equals(o.field2)) && (field3.equals(o.field3)) && ... (field100.equals(o.field100)); 

Вы можете использовать Apache Commons Beanutils. Вот простой пример:

 package at.percom.temp.zztests; import java.lang.reflect.InvocationTargetException; import org.apache.commons.beanutils.BeanMap; import org.apache.commons.beanutils.PropertyUtilsBean; import java.util.Arrays; import java.util.HashSet; import java.util.Objects; import java.util.Set; public class Main { public static void main(String[] args) throws IllegalAccessException, InvocationTargetException, NoSuchMethodException { Main main = new Main(); main.start(); } public void start() throws IllegalAccessException, InvocationTargetException, NoSuchMethodException { SampleBean oldSample = new SampleBean("John", "Doe", 1971); SampleBean newSample = new SampleBean("John X.", "Doe", 1971); SampleBean diffSample = (SampleBean) compareObjects(oldSample, newSample, new HashSet<>(Arrays.asList("lastName")), 10L); } public Object compareObjects(Object oldObject, Object newObject, Set propertyNamesToAvoid, Long deep) { return compareObjects(oldObject, newObject, propertyNamesToAvoid, deep, null); } private Object compareObjects(Object oldObject, Object newObject, Set propertyNamesToAvoid, Long deep, String parentPropertyPath) { propertyNamesToAvoid = propertyNamesToAvoid != null ? propertyNamesToAvoid : new HashSet<>(); parentPropertyPath = parentPropertyPath != null ? parentPropertyPath : ""; Object diffObject = null; try { diffObject = oldObject.getClass().newInstance(); } catch (Exception e) { return diffObject; } BeanMap map = new BeanMap(oldObject); PropertyUtilsBean propUtils = new PropertyUtilsBean(); for (Object propNameObject : map.keySet()) { String propertyName = (String) propNameObject; String propertyPath = parentPropertyPath + propertyName; if (!propUtils.isWriteable(diffObject, propertyName) || !propUtils.isReadable(newObject, propertyName) || propertyNamesToAvoid.contains(propertyPath)) { continue; } Object property1 = null; try { property1 = propUtils.getProperty(oldObject, propertyName); } catch (Exception e) { } Object property2 = null; try { property2 = propUtils.getProperty(newObject, propertyName); } catch (Exception e) { } try { if (property1 != null && property2 != null && property1.getClass().getName().startsWith("com.racing.company") && (deep == null || deep > 0)) { Object diffProperty = compareObjects(property1, property2, propertyNamesToAvoid, deep != null ? deep - 1 : null, propertyPath + "."); propUtils.setProperty(diffObject, propertyName, diffProperty); } else { if (!Objects.deepEquals(property1, property2)) { propUtils.setProperty(diffObject, propertyName, property2); System.out.println("> " + propertyPath + " is different (oldValue=\"" + property1 + "\", newValue=\"" + property2 + "\")"); } else { System.out.println(" " + propertyPath + " is equal"); } } } catch (Exception e) { } } return diffObject; } public class SampleBean { public String firstName; public String lastName; public int yearOfBirth; public SampleBean(String firstName, String lastName, int yearOfBirth) { this.firstName = firstName; this.lastName = lastName; this.yearOfBirth = yearOfBirth; } public String getFirstName() { return firstName; } public String getLastName() { return lastName; } public int getYearOfBirth() { return yearOfBirth; } } } 

Эй, посмотрите на Javers, это именно то, что вам нужно – объекты аудита и diff framework. С помощью Javers вы можете сохранить изменения, сделанные на объектах домена, с помощью одного javers.commit() после каждого обновления. Когда вы сохраняете некоторые изменения, вы можете легко прочитать их javers.getChangeHistory , например

 public static void main(String... args) { //get Javers instance Javers javers = JaversBuilder.javers().build(); //create java bean User user = new User(1, "John"); //commit current state javers.commit("author", user); //update operation user.setUserName("David"); //commit change javers.commit("author", user); //read 100 last changes List changes = javers.getChangeHistory(instanceId(1, User.class), 100); //print change log System.out.printf(javers.processChangeList(changes, new SimpleTextChangeLog())); } 

и выход:

 commit 2.0, author:author, 2015-01-07 23:00:10 changed object: org.javers.demo.User/1 value changed on 'userName' property: 'John' -> 'David' commit 1.0, author:author, 2015-01-07 23:00:10 new object: 'org.javers.demo.User/1 

Вы можете использовать reflection для загрузки полей, а затем вызывать их на каждом объекте и сравнивать результат.

Пример исходного кода может выглядеть так:

 public static  void Compare(T source, T target) throws IllegalArgumentException, IllegalAccessException { if(source == null) { throw new IllegalArgumentException("Null argument not excepted at this point"); } Field[] fields = source.getClass().getFields(); Object sourceObject; Object targetObject; for(Field field : fields){ sourceObject = field.get(source); targetObject = field.get(target); //Compare the object } } 

FYI, этот код будет работать только в общедоступных полях, объявленных для classа.

Вы можете использовать Apache BeanUtils для проверки свойств.

  • Как выполнить проверку в JSF, как создать пользовательский валидатор в JSF
  • Что такое JavaBean?
  • ClassFormatError: Отсутствует атрибут кода в методе, который не является родным или абстрактным в файле classа javax / mail / MessagingException
  • Разница между DTO, VO, POJO, JavaBeans?
  • Что такое class java pojo, java bean, обычный class?
  • Планирование JavaBean с помощью свойств JavaFX
  • Spring не может найти конфигурационный файл bean xml, если он существует
  • Использование компонента Sessionful Session для отслеживания сеанса пользователя
  • Interesting Posts

    Как реализовать коробку или гауссовское размытие на iPhone

    Сброс стека навигации для главного экрана (React Navigation and React Native)

    Должны ли хранилища streamов или действия (или оба) касаться внешних служб?

    Почему метод concat () Java не делает ничего?

    Excel – количество видимых ячеек, содержащих определенную строку.

    Как сделать часть регулярного выражения необязательной?

    IE10 SCRIPT5009: «__doPostBack» не определен

    Что такое команда Linux, чтобы узнать информацию об оборудовании?

    System.Data.SQLite Close () не освобождает файл базы данных

    Динамически отключать ядра мощным способом?

    Redis однопоточен, тогда как он выполняет параллельный ввод-вывод?

    Что такое справочный тип данных firestore?

    Невозможно перейти от родительского classа к classу детей

    Есть ли способ в Java определить, является ли путь действительным, не пытаясь создать файл?

    Запрос элемента видео HTML5 остается навсегда (на хроме)

    Давайте будем гением компьютера.