'Javers not recognizing insert as an initial change

Working on a SpringBoot application using MongoDB as a persistent store. Using spring data and MongoRepository to access MongoDB. Using Javers to provide auditting. If I use mongoRepository.insert(document) followed later by a mongoRepository.save(document) and then use javers to query the changes to that document, javers does not detect the differences between the object inserted and the object saved. It reports only a single change as if the save call was the original object persisted.

If I replace the insert call with a save and let spring data handle whether or not to insert or update, javers reports the expected change.

Example: Consider the following:

@JaversSpringDataAuditable
public interface SomeDocumentRepository extends MongoRepository<SomeDocument, String> {
}

@Builder
@Data
@Document(collection = "someDocuments")
public class SomeDocument {
    @Id
    private String id;
    private String status;
}

@Service
public class SomeDocumentService {
    @Autowired
    private SomeDocumentRepository someDocumentRepository;

    public SomeDocument insert(SomeDocument doc) {
        return someDocumentRepository.insert(doc);
    }

    public SomeDocument save(SomeDocument doc) {
        return someDocumentRepository.save(doc);
    }
}

@Service
public class AuditService {
    @Autowired
    private Javers javers;

    public List<Change> getStatusChangesById(String documentId) {
        JqlQuery query = QueryBuilder
            .byInstanceId(documentId, SomeDocument.class)
            .withChangedProperty("status")
            .build();
        return javers.findChanges(query);
    }
}

If I call my service as follows:

var doc = SomeDocument.builder().status("new").build();
doc = someDocumentService.insert(doc);
doc.setStatus("change1");
doc = someDocumentService.save(doc);

and then call the audit service to get the changes:

auditService.getStatusChangesById(doc.getId());

I get a single change with "left" set to a blank and "right" set to "change1".

If I call "save" instead of "insert" like:

var doc = SomeDocument.builder().status("new").build();
doc = someDocumentService.save(doc);
doc.setStatus("change1");
doc = someDocumentService.save(doc);

and then call the audit service to get the changes I get 2 changes, the first being the most recent change with "left" set to "new", and "right" set to "change1" and a second change with "left" set to "" and "right" set to "new".

Is this a bug?



Solution 1:[1]

That's a good point. In case of Mongo, Javers covers only the methods from the CrudRepository interface. See https://github.com/javers/javers/blob/master/javers-spring/src/main/java/org/javers/spring/auditable/aspect/springdata/JaversSpringDataAuditableRepositoryAspect.java

Looks like MongoRepository#insert() should be also covered by the aspect.

Feel free to contribute a PR to javers, I will merge it. If you want to discuss the design first - please create a discussion here https://github.com/javers/javers/discussions

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Bartek Walacik