public interface Javers
JaversBuilder provided with your domain model configuration.
Javers javers = JaversBuilder.javers().build(); Diff diff = javers.compare(oldVersion, currentVersion);
| Modifier and Type | Method | Description |
|---|---|---|
Commit |
commit(java.lang.String author,
java.lang.Object currentVersion) |
Persists a current state of a given domain object graph
in JaVers repository.
|
Commit |
commit(java.lang.String author,
java.lang.Object currentVersion,
java.util.Map<java.lang.String,java.lang.String> commitProperties) |
Variant of
commit(String, Object) with commitProperties. |
java.util.concurrent.CompletableFuture<Commit> |
commitAsync(java.lang.String author,
java.lang.Object currentVersion,
java.util.concurrent.Executor executor) |
Async version of
commit(String, Object)
Important! Works with MongoDB, not implemented for SQL repositories. |
java.util.concurrent.CompletableFuture<Commit> |
commitAsync(java.lang.String author,
java.lang.Object currentVersion,
java.util.Map<java.lang.String,java.lang.String> commitProperties,
java.util.concurrent.Executor executor) |
Async version of
commit(String, Object, Map)
Important! Works with MongoDB, not implemented for SQL repositories. |
Commit |
commitShallowDelete(java.lang.String author,
java.lang.Object deleted) |
Marks given object as deleted.
|
Commit |
commitShallowDelete(java.lang.String author,
java.lang.Object deleted,
java.util.Map<java.lang.String,java.lang.String> commitProperties) |
Variant of
commitShallowDelete(String, Object) with commitProperties. |
Commit |
commitShallowDeleteById(java.lang.String author,
GlobalIdDTO globalId) |
The same like
commitShallowDelete(String,Object)
but deleted object is selected using globalId |
Commit |
commitShallowDeleteById(java.lang.String author,
GlobalIdDTO globalId,
java.util.Map<java.lang.String,java.lang.String> commitProperties) |
Variant of
commitShallowDeleteById(String, GlobalIdDTO) with commitProperties. |
Diff |
compare(java.lang.Object oldVersion,
java.lang.Object currentVersion) |
Deep compare
|
<T> Diff |
compareCollections(java.util.Collection<T> oldVersion,
java.util.Collection<T> currentVersion,
java.lang.Class<T> itemClass) |
Deeply compares two top-level collections.
|
Changes |
findChanges(JqlQuery query) |
Queries a JaversRepository for change history (diff sequence) of a given class, object or property.
Returns the list of Changes. There are various types of changes. |
<T> java.util.List<Shadow<T>> |
findShadows(JqlQuery query) |
Queries JaversRepository for object Shadows.
|
<T> java.util.stream.Stream<Shadow<T>> |
findShadowsAndStream(JqlQuery query) |
Streamed version of
findShadows(JqlQuery). |
java.util.List<CdoSnapshot> |
findSnapshots(JqlQuery query) |
Queries JaversRepository for object Snapshots.
|
java.util.Optional<CdoSnapshot> |
getHistoricalSnapshot(java.lang.Object localId,
java.lang.Class entity,
java.time.LocalDateTime effectiveDate) |
Historical snapshot of a given Entity instance.
|
JsonConverter |
getJsonConverter() |
If you are serializing JaVers objects like
Commit, Change, Diff or CdoSnapshot to JSON, use this JsonConverter. |
java.util.Optional<CdoSnapshot> |
getLatestSnapshot(java.lang.Object localId,
java.lang.Class entity) |
Latest snapshot of a given Entity instance.
|
Property |
getProperty(PropertyChange propertyChange) |
Returns
Property which underlies given PropertyChange |
<T extends JaversType> |
getTypeMapping(java.lang.reflect.Type userType) |
Use JaversTypes, if you want to:
- describe your class in the context of JaVers domain model mapping, - use JaVers Reflection API to conveniently access your object properties (instead of awkward java.lang.reflect API). |
Diff |
initial(java.lang.Object newDomainObject) |
Initial diff is a kind of snapshot of a given object graph.
|
<T> T |
processChangeList(java.util.List<Change> changes,
ChangeProcessor<T> changeProcessor) |
Generic purpose method for processing a changes list.
|
Commit commit(java.lang.String author, java.lang.Object currentVersion)
author - current usercurrentVersion - standalone object or handle to an object graphCommit commit(java.lang.String author, java.lang.Object currentVersion, java.util.Map<java.lang.String,java.lang.String> commitProperties)
commit(String, Object) with commitProperties.
commitProperties - for example ["channel":"web", "locale":"pl-PL"]QueryBuilder.withCommitProperty(String, String)java.util.concurrent.CompletableFuture<Commit> commitAsync(java.lang.String author, java.lang.Object currentVersion, java.util.concurrent.Executor executor)
commit(String, Object)
executor - ExecutorService to be used to process commit() asynchronouslyjava.util.concurrent.CompletableFuture<Commit> commitAsync(java.lang.String author, java.lang.Object currentVersion, java.util.Map<java.lang.String,java.lang.String> commitProperties, java.util.concurrent.Executor executor)
commit(String, Object, Map)
executor - ExecutorService to be used to process commit() asynchronouslyCommit commitShallowDelete(java.lang.String author, java.lang.Object deleted)
commit(String, Object), this method is shallow
and affects only given object.
deleted - object to be marked as deletedCommit commitShallowDelete(java.lang.String author, java.lang.Object deleted, java.util.Map<java.lang.String,java.lang.String> commitProperties)
commitShallowDelete(String, Object) with commitProperties.
commit(String, Object, Map) for commitProperties description.Commit commitShallowDeleteById(java.lang.String author, GlobalIdDTO globalId)
commitShallowDelete(String,Object)
but deleted object is selected using globalIdCommit commitShallowDeleteById(java.lang.String author, GlobalIdDTO globalId, java.util.Map<java.lang.String,java.lang.String> commitProperties)
commitShallowDeleteById(String, GlobalIdDTO) with commitProperties.
commit(String, Object, Map) for commitProperties description.Diff compare(java.lang.Object oldVersion, java.lang.Object currentVersion)
To calculate a diff, just provide two versions of the
same Domain Object (Entity or ValueObject)
or handles to two versions of the same object graph.
The handle could be a root of an Aggregate, tree root
or any node in an Domain Object graph from where all other nodes are navigable.
Object.equals(Object). compare() function is used for ad-hoc objects comparing.
In order to use data auditing feature, call commit(String, Object).
Diffs can be converted to JSON with JsonConverter.toJson(Object) or pretty-printed with Diff.prettyPrint()
<T> Diff compareCollections(java.util.Collection<T> oldVersion, java.util.Collection<T> currentVersion, java.lang.Class<T> itemClass)
compare(Object, Object).
List<Person> oldList = ... List<Person> newList = ... Diff diff = javers.compareCollections(oldList, newList, Person.class);
Diff initial(java.lang.Object newDomainObject)
<T> java.util.List<Shadow<T>> findShadows(JqlQuery query)
ListSince Shadows are instances of your domain classes, you can use them directly in your application:shadows = javers.findShadows( QueryBuilder.byInstanceId("bob", Person.class) .limit(5).build() );
assert shadows.get(0).get() instanceof Person.class;
// E1 -> E2 -> E3 -> E4 def e4 = new Entity(id:4) def e3 = new Entity(id:3, ref:e4) def e2 = new Entity(id:2, ref:e3) def e1 = new Entity(id:1, ref:e2)
given:
javers.commit("author", e4) // commit 1.0 with e4 snapshot
javers.commit("author", e3) // commit 2.0 with e3 snapshot
javers.commit("author", e1) // commit 3.0 with snapshots of e1 and e2
when: 'shallow scope query'
def shadows = javers.findShadows(QueryBuilder.byInstanceId(1, Entity)
.build())
def shadowE1 = shadows.get(0).get()
then: 'only e1 is loaded'
shadowE1 instanceof Entity
shadowE1.id == 1
shadowE1.ref == null
when: 'commit-deep scope query'
shadows = javers.findShadows(QueryBuilder.byInstanceId(1, Entity)
.withScopeCommitDeep().build())
shadowE1 = shadows.get(0).get()
then: 'only e1 and e2 are loaded, both was committed in commit 3.0'
shadowE1.id == 1
shadowE1.ref.id == 2
shadowE1.ref.ref == null
when: 'deep+1 scope query'
shadows = javers.findShadows(QueryBuilder.byInstanceId(1, Entity)
.withScopeDeepPlus(1).build())
shadowE1 = shadows.get(0).get()
then: 'only e1 + e2 are loaded'
shadowE1.id == 1
shadowE1.ref.id == 2
shadowE1.ref.ref == null
when: 'deep+3 scope query'
shadows = javers.findShadows(QueryBuilder.byInstanceId(1, Entity)
.withScopeDeepPlus(3).build())
shadowE1 = shadows.get(0).get()
then: 'all object are loaded'
shadowE1.id == 1
shadowE1.ref.id == 2
shadowE1.ref.ref.id == 3
shadowE1.ref.ref.ref.id == 4
given:
javers.commit("author", e1) //commit 1.0 with snapshots of e1, e2, e3 and e4
when: 'commit-deep scope query'
shadows = javers.findShadows(QueryBuilder.byInstanceId(1, Entity)
.withScopeCommitDeep().build())
shadowE1 = shadows.get(0).get()
then: 'all object are loaded'
shadowE1.id == 1
shadowE1.ref.id == 2
shadowE1.ref.ref.id == 3
shadowE1.ref.ref.ref.id == 4
<logger name="org.javers.JQL" level="DEBUG"/>Example debug for a Shadow query execution:
DEBUG org.javers.JQL - SHALLOW query: 1 snapshots loaded (entities: 1, valueObjects: 0)
DEBUG org.javers.JQL - DEEP_PLUS query for '...SnapshotEntity/2' at commitId 3.0, 1 snapshot(s) loaded, gaps filled so far: 1
DEBUG org.javers.JQL - warning: object '...SnapshotEntity/3' is outside of the DEEP_PLUS+1 scope, references to this object will be nulled. Increase maxGapsToFill and fill all gaps in your object graph.
DEBUG org.javers.JQL - queryForShadows executed:
JqlQuery {
IdFilter{ globalId: ...SnapshotEntity/1 }
QueryParams{ aggregate: true, limit: 100 }
ShadowScopeDefinition{ shadowScope: DEEP_PLUS, maxGapsToFill: 1 }
Stats{
executed in millis: 12
DB queries: 2
all snapshots: 2
SHALLOW snapshots: 1
DEEP_PLUS snapshots: 1
gaps filled: 1
gaps left!: 1
}
}
Execution stats are also available in JqlQuery.stats().T - type of a domain objectQueryBuilder.limit(int)
limits the number of Snapshots loaded in the base query
and not the number of returned Shadows
(one Shadow can be reconstructed from many Snapshots).
The only correct way for paging Shadows is findShadowsAndStream(JqlQuery)
with Stream.skip(long) and Stream.limit(long).ShadowScope,
http://javers.org/documentation/jql-examples<T> java.util.stream.Stream<Shadow<T>> findShadowsAndStream(JqlQuery query)
findShadows(JqlQuery).
Stream.skip(long) and Stream.limit(long)
is the only correct way for paging Shadows.T - type of a domain objectfindShadows(JqlQuery)Changes findChanges(JqlQuery query)
Change class hierarchy.Changes can be easily traversed using Changes.groupByCommit() and Changes.groupByObject().
javers.findChanges( QueryBuilder.byInstanceId("bob", Person.class).limit(5).build() );
Last "salary" changes of "bob" Person:
javers.findChanges( QueryBuilder.byInstanceId("bob", Person.class).withChangedProperty("salary").build() );
Querying for ValueObject changes
javers.findChanges( QueryBuilder.byValueObjectId("bob", Person.class, "address").build() );
Last changes on Address ValueObject owned by any Person:
javers.findChanges( QueryBuilder.byValueObject(Person.class, "address").build() );Last changes on nested ValueObject (when Address is a ValueObject nested in PersonDetails ValueObject):
javers.findChanges( QueryBuilder.byValueObject(Person.class, "personDetails/address").build() );Querying for any object changes by its class
javers.findChanges( QueryBuilder.byClass(MyClass.class).build() );Last "myProperty" changes on any object of MyClass.class:
javers.findChanges( QueryBuilder.byClass(Person.class).withChangedProperty("myProperty").build() );
java.util.List<CdoSnapshot> findSnapshots(JqlQuery query)
javers.findSnapshots( QueryBuilder.byInstanceId("bob", Person.class).limit(5).build() );
For more query examples, see findChanges(JqlQuery) method.
java.util.Optional<CdoSnapshot> getLatestSnapshot(java.lang.Object localId, java.lang.Class entity)
Bob, call:
javers.getLatestSnapshot("bob", Person.class);
Returns Optional#EMPTY if an instance is not versioned.java.util.Optional<CdoSnapshot> getHistoricalSnapshot(java.lang.Object localId, java.lang.Class entity, java.time.LocalDateTime effectiveDate)
Bob at 2017-01-01, call:
javers.getHistoricalSnapshot("bob", Person.class, LocalDateTime.of(2017,01,01));
Returns Optional#EMPTY if an instance is not versioned.JsonConverter getJsonConverter()
Commit, Change, Diff or CdoSnapshot to JSON, use this JsonConverter.
javers.getJsonConverter().toJson(changes);
<T> T processChangeList(java.util.List<Change> changes, ChangeProcessor<T> changeProcessor)
ChangeProcessor.result().
ChangeProcessor.onCommit(CommitMetadata)
is called only for first occurrence ChangeProcessor.onAffectedObject(GlobalId)
is called only for first occurrence
List<Change> changes = javers.calculateDiffs(...); String changeLog = javers.processChangeList(changes, new SimpleTextChangeLog()); System.out.println( changeLog );
SimpleTextChangeLog<T extends JaversType> T getTypeMapping(java.lang.reflect.Type userType)
class Person {
@Id int id;
@Transient String notImportantField;
String name;
}
Calling
System.out.println( javers.getTypeMapping(Person.class).prettyPrint() );prints:
EntityType{
baseType: org.javers.core.examples.Person
managedProperties:
Field int id; //declared in: Person
Field String name; //declared in: Person
idProperty: login
}
Property access example.
You can list object property values using Property abstraction.
Javers javers = JaversBuilder.javers().build();
ManagedType jType = javers.getTypeMapping(Person.class);
Person person = new Person("bob", "Uncle Bob");
System.out.println("Bob's properties:");
for (Property p : jType.getPropertyNames()){
Object value = p.get(person);
System.out.println( "property:" + p.getName() + ", value:" + value );
}
prints:
Bob's properties: property:login, value:bob property:name, value:Uncle Bob
Property getProperty(PropertyChange propertyChange)
Property which underlies given PropertyChange