2

My exact requirement is to log the values of old object and new object together. for example if previously the name of the user was "AAA" and somebody changes the name to "CCC" than in service layer I need to log like this "user name changes from AAA to CCC dated 10-09-2013". Please provide some solution in spring framework.

Aditya
  • 21
  • 1
  • 6

2 Answers2

1

Spring doesn't provide any such functionality, as far as I know.

However, what you want is quite easy to achieve: Use Reflection, or go with BeanUtils, which uses Reflection internally anyway. Using either of these, you can iterate over the properties of your objects and create a Map or something that contains the necessary details. Take a look at these two answers:

common-algorithm-for-generating-a-diff-of-the-fields-in-two-beans

find-out-the-differences-between-two-java-beans-for-version-tracking

Or, there is a library named java-object-diff out there that can do it for you. It also supports deep object comparison, and handles a lot of complexity for you.

Also, you might be interested in this JIRA issue with BeanUtils. See the comments section.

Community
  • 1
  • 1
Bhashit Parikh
  • 3,051
  • 21
  • 24
1

You can use Spring AOP, intercept bean's setters and log property change, basic idea is here

class B1 {
    String name = "xxx";
    public void setName(String name) {
        this.name = name;
    }
    public String getName() {
        return name;
    }
}

@Aspect
class A1 {
    @Before("execution(void test.B1.set*(*))")
    public void before(JoinPoint jp) throws Exception {
        String prop = jp.getSignature().getName().substring(3);
        Object target = jp.getTarget();
        Object before = target.getClass().getMethod("get" + prop).invoke(target);
        Object now = jp.getArgs()[0];
        System.out.println(prop + " changed from " + before + " to " + now);
    }
}

public class Test1 {

    public static void main(String[] args) throws Exception {
        ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("test1.xml");
        B1 b1 = ctx.getBean(B1.class);
        b1.setName("yyy");
    }
}

this prints

Name changed from xxx to yyy

test1.xml

...
    <context:annotation-config />
    <aop:aspectj-autoproxy />
    <bean class="test.B1" />
    <bean class="test.A1" />
...
Evgeniy Dorofeev
  • 129,181
  • 28
  • 195
  • 266