javaauditjavers

With Javers, how to commit object with Map property?


the usecase is to audit data changes of documents in a mongodb collection, and the global key(which can identify a specific document) is needed when edited data commit, just like:

globalId_key: "MyRecord/333"

so I wrapped a DTO object as below:

import jakarta.persistence.Id;
import lombok.Data;
import org.bson.Document;
import org.javers.core.metamodel.annotation.TypeName;

@TypeName("MyRecord")
@Data
public class RecordDto {

    @Id
    private Long recordId;

    private Document data;

}

the data property has many entries and each entry's value was limited to types:int, long, string only.

but when I commit this edited record, the audit info always report only 1 property("data") changes, how to make the changed entries present in changes properties?

i have thought about to commit the Document object directly, but it can not generate record id.

how to deal with this situation?


Solution

  • i found the reason at last.

    the audit info always report only 1 property("data") changes
    

    yes, it is! but the change of the property "data" is a MapChange, but not ValueChange, we can get the changed entries from MapChange.

    javers provides many change type for Map's entry change, such as: EntryValueChange, EntryAdded, EntryRemoved.

    here is sample code to get changes from a MapChange:

    if(change instanceof MapChange<?> mc){
        List<EntryChange> entries = mc.getEntryChanges();
        for(EntryChange entry: entries){
            String key = entry.getKey().toString(); // key of map entry
            if(entry instanceof EntryValueChange evc){
                Object left = evc.getLeftValue();   // value before commit
                Object right = evc.getRightValue(); // value after commit
            } else if(entry instanceof EntryAdded ea){
                Object value = ea.getValue();   // value of added entry of map
            } else if(entry instanceof EntryRemoved er){
                Object value = er.getValue();   // value of removed entry of map
            }
        }
    }