Audit Property change - Spring MVC+ JPA

Irakli

I have a class Client. I want to be able to audit the changes of property of this class(not entire class - just it's properties).

public class Client {
private Long id;
private String firstName;
private String lastName;
private String email;
private String mobileNumber;
private Branch companyBranch;

actually this is very easy to audit the whole entity with @Audited annotation.

But what I want is to audit this changes using my class structure.

here is my desired result class:

public class Action {
private String fieldName;
private String oldValue;
private String newValue;
private String action;
private Long modifiedBy;
private Date changeDate;
private Long clientID;

the result should look like this:

fieldName + "was changed from " + oldValue + "to" + newValue + "for" clientID +"by" modifiedBy;

  • mobileNumber was changed from 555 to 999 for Bill Gates by George.

The reason I'm doing this is that I need to store this changes into DB under Action table - because I will be Auditing properties from different Entities and I want to store that together and then have a ability to get them when I need.

How can I do this?

Thanks

Sergey Bespalov

Aop is right way to go. You can use AspectJ with field set() pointcut for your needs. With before aspect you can extract necessary info to populate Action object.

Also you can use custom class Annotation @AopAudit to detect classes you want to audit. You must define such annotation in your classpath and place in under target classes which you want to audit.

This approach can look like this:

AopAudit.java

@Retention(RUNTIME)
@Target(TYPE)
public @interface AopAudit {

}

Client.java

@AopAudit
public class Client {
    private Long id;
    private String firstName;
    private String lastName;
    private String email;
    private String mobileNumber;
}

AuditAnnotationAspect.aj

import org.aspectj.lang.reflect.FieldSignature;

import java.lang.reflect.Field;

public aspect FieldAuditAspect {

pointcut auditField(Object t, Object value): set(@(*.AopAudit) * *.*) && args(value) && target(t);

pointcut auditType(Object t, Object value): set(* @(*.AopAudit) *.*) && args(value) && target(t);

before(Object target, Object newValue): auditField(target, newValue) || auditType(target, newValue) {
        FieldSignature sig = (FieldSignature) thisJoinPoint.getSignature();
        Field field = sig.getField(); 
        field.setAccessible(true);

        Object oldValue;
        try
        {
            oldValue = field.get(target);
        }
        catch (IllegalAccessException e)
        {
            throw new RuntimeException("Failed to create audit Action", e);
        }

        Action a = new Action();
        a.setFieldName(sig.getName());
        a.setOldValue(oldValue == null ? null : oldValue.toString());
        a.setNewValue(newValue == null ? null : newValue.toString());
    }

}

This is AspectJ aspect that define auditField pointcut to capture field set operations and before logic to create Audit object.

To enable AspectJ Compile Time Weaving you must do the following in case of Maven:

pom.xml

...

<dependencies>
    <dependency>
        <groupId>org.aspectj</groupId>
        <artifactId>aspectjrt</artifactId>
    </dependency>
</dependencies>

...

<plugins>
    <plugin>
        <groupId>org.codehaus.mojo</groupId>
        <artifactId>aspectj-maven-plugin</artifactId>
        <version>1.6</version>
        <configuration>
            <showWeaveInfo>true</showWeaveInfo>
            <source>${java.source}</source>
            <target>${java.target}</target>
            <complianceLevel>${java.target}</complianceLevel>
            <encoding>UTF-8</encoding>
            <verbose>false</verbose>
            <XnoInline>false</XnoInline>
        </configuration>
        <executions>
            <execution>
                <id>aspectj-compile</id>
                <goals>
                    <goal>compile</goal>
                </goals>
            </execution>
            <execution>
                <id>aspectj-compile-test</id>
                <goals>
                    <goal>test-compile</goal>
                </goals>
            </execution>
        </executions>
        <dependencies>
            <dependency>
                <groupId>org.aspectj</groupId>
                <artifactId>aspectjrt</artifactId>
                <version>${aspectj.version}</version>
            </dependency>
            <dependency>
                <groupId>org.aspectj</groupId>
                <artifactId>aspectjtools</artifactId>
                <version>${aspectj.version}</version>
            </dependency>
        </dependencies>
    </plugin>
</plugins>

This Maven configuration enables AspectJ compiler that makes bytecode post processing of your classes.

applicationContext.xml

<bean class="AuditAnnotationAspect" factory-method="aspectOf"/>

Also you may need to add aspect instance to Spring Application Context for dependency injection.

UPD: Here is an example of such AspectJ project configuration

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related

From Dev

Audit Property change - Spring MVC+ JPA

From Dev

Envers: wrong audit table on a Spring MVC project

From Dev

Envers: wrong audit table on a Spring MVC project

From Dev

Spring MVC with JPA databinding

From Dev

Spring MVC with Spring Data JPA

From Java

Exclude some fields from audit with Spring Data JPA @LastModifiedDate

From Dev

Custom queries in JPA in Spring MVC

From Dev

Change URL in spring mvc

From Java

Spring Data JPA find by embedded object property

From Dev

Spring Data JPA - Is it possible to sort on a calculated property?

From Dev

Spring data JPA JPQL query on child property

From Dev

Why is the version property not set with Spring Data JPA?

From Dev

Spring boot property injection to JPA entity definitions

From Dev

Spring JPA Hibernate Auto Populate Audit Fields (Create ID / Timestamp etc)

From Dev

How to save timestamp in UTC format for Audit fields @CreatedDate, @LastModifiedDate in Spring JPA

From Dev

Are DAOs still needed in Spring MVC with JPA/Hibernate

From Dev

ClassNotFoundException: derby ClientDriver (Spring MVC + Hibernate JPA)

From Dev

Multiple Schema Configuration On Spring MVC + Hibernate + JPA

From Dev

EAGER and Pagination : Spring MVC + JPA Repository + Hibernate

From Dev

Change how Spring JPA does pagination

From Java

What is this spring.jpa.open-in-view=true property in Spring Boot?

From Dev

Using Property files in Spring 4 MVC

From Dev

spring data jpa maven dependencies jars not exported to spring mvc project

From Dev

Filtering database rows with spring-data-jpa and spring-mvc

From Dev

spring data jpa maven dependencies jars not exported to spring mvc project

From Dev

How to update data with Hibernate and Spring JPA in Spring MVC

From Dev

Spring Boot: Change property placeholder signifier

From Dev

How to change/update/delete a property in ConfigurableEnvironment of Spring

From Dev

How change property values at runtime in Spring

Related Related

  1. 1

    Audit Property change - Spring MVC+ JPA

  2. 2

    Envers: wrong audit table on a Spring MVC project

  3. 3

    Envers: wrong audit table on a Spring MVC project

  4. 4

    Spring MVC with JPA databinding

  5. 5

    Spring MVC with Spring Data JPA

  6. 6

    Exclude some fields from audit with Spring Data JPA @LastModifiedDate

  7. 7

    Custom queries in JPA in Spring MVC

  8. 8

    Change URL in spring mvc

  9. 9

    Spring Data JPA find by embedded object property

  10. 10

    Spring Data JPA - Is it possible to sort on a calculated property?

  11. 11

    Spring data JPA JPQL query on child property

  12. 12

    Why is the version property not set with Spring Data JPA?

  13. 13

    Spring boot property injection to JPA entity definitions

  14. 14

    Spring JPA Hibernate Auto Populate Audit Fields (Create ID / Timestamp etc)

  15. 15

    How to save timestamp in UTC format for Audit fields @CreatedDate, @LastModifiedDate in Spring JPA

  16. 16

    Are DAOs still needed in Spring MVC with JPA/Hibernate

  17. 17

    ClassNotFoundException: derby ClientDriver (Spring MVC + Hibernate JPA)

  18. 18

    Multiple Schema Configuration On Spring MVC + Hibernate + JPA

  19. 19

    EAGER and Pagination : Spring MVC + JPA Repository + Hibernate

  20. 20

    Change how Spring JPA does pagination

  21. 21

    What is this spring.jpa.open-in-view=true property in Spring Boot?

  22. 22

    Using Property files in Spring 4 MVC

  23. 23

    spring data jpa maven dependencies jars not exported to spring mvc project

  24. 24

    Filtering database rows with spring-data-jpa and spring-mvc

  25. 25

    spring data jpa maven dependencies jars not exported to spring mvc project

  26. 26

    How to update data with Hibernate and Spring JPA in Spring MVC

  27. 27

    Spring Boot: Change property placeholder signifier

  28. 28

    How to change/update/delete a property in ConfigurableEnvironment of Spring

  29. 29

    How change property values at runtime in Spring

HotTag

Archive