say i have a java bean/an entity with 100 fields (inherited or not it is not relevant in this case). After update operations - in a transaction, i want to determine which fields are modified to track updates like a CVS. What is the easiest way to do this? Any Framework suggestion? Should i make two instances of this object and iterate over all fields and match the values of fields ? How would the best equals method seem in such situations ? The following equals() seems very awkward :
return (field1.equals(o.field1)) && (field2.equals(o.field2)) && (field3.equals(o.field3)) && ... (field100.equals(o.field100));
The main difference between EJB and Java Beans is that the EJB is a server-side software component that encapsulates the business logic of an application while JavaBeans are classes that encapsulates multiple objects into a single object that helps to create reusable software components for Java.
The only difference between both the classes is Java make java beans objects serialized so that the state of a bean class could be preserved in case required.So due to this a Java Bean class must either implements Serializable or Externalizable interface.
A JavaBean is a Java class that encapsulates multiple objects and conforms to certain conventions. JavaBeans are used mainly for client-side development. An enterprise bean (EJB) is a Java class imbued with specific server-side capabilities. Enterprise beans are used in large-scale business applications and systems.
JavaBeans is a portable, platform-independent model written in Java Programming Language. Its components are referred to as beans. In simple terms, JavaBeans are classes which encapsulate several objects into a single object. It helps in accessing these object from multiple places.
You could use Apache Commons Beanutils. Here's a simple example:
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<String> propertyNamesToAvoid, Long deep) { return compareObjects(oldObject, newObject, propertyNamesToAvoid, deep, null); } private Object compareObjects(Object oldObject, Object newObject, Set<String> 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; } } }
Hey look at Javers it's exactly what you need - objects auditing and diff framework . With Javers you can persist changes done on your domain objects with a single javers.commit()
call after every update. When you persist some changes you can easily read them by javers.getChangeHistory
, e.g.
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<Change> changes = javers.getChangeHistory(instanceId(1, User.class), 100); //print change log System.out.printf(javers.processChangeList(changes, new SimpleTextChangeLog())); }
and the output is:
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With