Package org.javers.core
Class JaversBuilder
java.lang.Object
org.javers.core.AbstractContainerBuilder
org.javers.core.JaversBuilder
Creates a JaVers instance based on your domain model metadata and custom configuration.
For example, to build a JaVers instance configured with reasonable defaults:
For example, to build a JaVers instance configured with reasonable defaults:
Javers javers = JaversBuilder.javers().build();To build a JaVers instance with an Entity type:
Javers javers = JaversBuilder.javers()
.registerEntity(MyEntity.class)
.build();
-
Field Summary
Fields -
Constructor Summary
Constructors -
Method Summary
Modifier and TypeMethodDescriptionprotected Javersprotected Javersbuild()static JaversBuilderjavers()<T> JaversBuilderregisterCustomComparator(CustomPropertyComparator<T, ?> comparator, Class<T> customType) Deprecated.<T> JaversBuilderregisterCustomType(Class<T> customType, CustomPropertyComparator<T, ?> comparator) Registers aCustomPropertyComparatorfor a given class and maps this class toCustomType.registerEntities(Class<?>... entityClasses) registerEntity(Class<?> entityClass) Registers anEntityType.registerEntity(EntityDefinition entityDefinition) Registers anEntityType.registerIgnoredClass(Class<?> ignoredClass) Marks given class as ignored by JaVers.registerIgnoredClassesStrategy(IgnoredClassesStrategy ignoredClassesStrategy) A dynamic version ofregisterIgnoredClass(Class).registerJaversRepository(JaversRepository repository) Registers an advanced variant of custom JSON TypeAdapter.registerObjectHasher(Class<? extends ObjectHasher> objectHasherType) Register a customObjectHasherimplementation, which is used to identify Value Objects inside Sets.registerType(ClientsClassDefinition clientsClassDefinition) Generic version ofregisterEntity(EntityDefinition)andregisterValueObject(ValueObjectDefinition)registerTypes(Collection<ClientsClassDefinition> clientsClassDefinitions) registerValue(Class<?> valueClass) Registers a simple value type (seeValueType).<T> JaversBuilderregisterValue(Class<T> valueClass, BiFunction<T, T, Boolean> equalsFunction) Deprecated.<T> JaversBuilderregisterValue(Class<T> valueClass, BiFunction<T, T, Boolean> equalsFunction, Function<T, String> toStringFunction) Lambda-style variant ofregisterValue(Class, CustomValueComparator).<T> JaversBuilderregisterValue(Class<T> valueClass, CustomValueComparator<T> customValueComparator) Registers aValueTypewith a custom comparator to be used instead ofObject.equals(Object).registerValueGsonTypeAdapter(Class valueType, com.google.gson.TypeAdapter nativeAdapter) registerValueObject(Class<?> valueObjectClass) Registers aValueObjectType.registerValueObject(ValueObjectDefinition valueObjectDefinition) Registers aValueObjectType.registerValueObjects(Class<?>... valueObjectClasses) registerValueTypeAdapter(JsonTypeAdapter typeAdapter) Registers aValueTypeand its custom JSON TypeAdapter.<T> JaversBuilderregisterValueWithCustomToString(Class<T> valueClass, Function<T, String> toStringFunction) Deprecated.scanTypeName(Class userType) Register your class with @TypeNameannotation in order to use it in all kinds of JQL queries.withCommitIdGenerator(CommitIdGenerator commitIdGenerator) CommitIdGenerator.SYNCHRONIZED_SEQUENCE— for non-distributed applicationsCommitIdGenerator.RANDOM— for distributed applications SYNCHRONIZED_SEQUENCE is used by default.withCustomCommitIdGenerator(Supplier<CommitId> commitIdGenerator) withDateTimeProvider(DateProvider dateProvider) DateProvider providers current timestamp forCommit.getCommitDate().withInitialChanges(boolean initialChanges) The Initial Changes switch, enabled by default since Javers 6.0.withListCompareAlgorithm(ListCompareAlgorithm algorithm) Choose between two algorithms for comparing list: ListCompareAlgorithm.SIMPLE or ListCompareAlgorithm.LEVENSHTEIN_DISTANCE.withMappingStyle(MappingStyle mappingStyle) Default style isMappingStyle.FIELD.withNewObjectsSnapshot(boolean newObjectsSnapshot) Deprecated.withObjectAccessHook(ObjectAccessHook objectAccessHook) withPackagesToScan(String packagesToScan) Comma separated list of packages scanned by Javers in search of your classes with theTypeNameannotation.withPrettyPrint(boolean prettyPrint) choose between JSON pretty or concise printing style, i.e.withPrettyPrintDateFormats(JaversCoreProperties.PrettyPrintDateFormats prettyPrintDateFormats) withProperties(JaversCoreProperties javersProperties) withTerminalChanges(boolean terminalChanges) The Terminal Changes switch, enabled by default since Javers 6.0.withTypeSafeValues(boolean typeSafeValues) Switch on when you need a type safe serialization for heterogeneous collections like List, List<Object>.withUsePrimitiveDefaults(boolean usePrimitiveDefaults) The Use Primitive Defaults switch, enabled by default.Methods inherited from class org.javers.core.AbstractContainerBuilder
addComponent, addModule, addModule, bindComponent, bootContainer, getComponents, getContainer, getContainerComponent, removeComponent
-
Field Details
-
logger
public static final org.slf4j.Logger logger
-
-
Constructor Details
-
JaversBuilder
protected JaversBuilder()use static factory methodjavers()
-
-
Method Details
-
javers
-
build
-
assembleJaversInstanceAndEnsureSchema
-
assembleJaversInstance
-
registerObjectHasher
Register a customObjectHasherimplementation, which is used to identify Value Objects inside Sets. The default implementation compares objects by value using JSON serialization state, seeSnapshotObjectHasher.
Alternative implementation —HashCodeObjectHasheruses standard JavaObject.hashCode()to identify Value Objects inside Sets. This approach can be beneficial if you for some reason don't want to map a given Value Object type as Entity but still you want this type to be identifiable inside Sets.- See Also:
-
registerJaversRepository
-
registerEntity
Registers anEntityType.
Use @Id annotation to mark exactly one Id-property.
Optionally, use @Transient or @DiffIgnoreannotations to mark ignored properties.
For example, Entities are: Person, Document -
registerValueObject
Registers aValueObjectType.
Optionally, use @Transient or @DiffIgnoreannotations to mark ignored properties.
For example, ValueObjects are: Address, Point -
registerEntity
Registers anEntityType.
Use this method if you are not willing to useEntityannotation.
Recommended way to createEntityDefinitionisEntityDefinitionBuilder, for example:javersBuilder.registerEntity( EntityDefinitionBuilder.entityDefinition(Person.class) .withIdPropertyName("id") .withTypeName("Person") .withIgnoredProperties("notImportantProperty","transientProperty") .build());For simple cases, you can useEntityDefinitionconstructors, for example:javersBuilder.registerEntity( new EntityDefinition(Person.class, "login") );
-
registerType
Generic version ofregisterEntity(EntityDefinition)andregisterValueObject(ValueObjectDefinition) -
registerTypes
-
registerValueObject
Registers aValueObjectType.
Use this method if you are not willing to useValueObjectannotations.
Recommended way to createValueObjectDefinitionisValueObjectDefinitionBuilder. For example:javersBuilder.registerValueObject(ValueObjectDefinitionBuilder.valueObjectDefinition(Address.class) .withIgnoredProperties(ignoredProperties) .withTypeName(typeName) .build();For simple cases, you can useValueObjectDefinitionconstructors, for example:javersBuilder.registerValueObject( new ValueObjectDefinition(Address.class, "ignored") );
-
withPackagesToScan
Comma separated list of packages scanned by Javers in search of your classes with theTypeNameannotation.
It's important to declare here all of your packages containing classes with @TypeName,
because Javers needs live class definitions to properly deserialize Snapshots fromJaversRepository.
For example, consider this class:@Entity @TypeName("Person") class Person { @Id private int id; private String name; }In the scenario when Javers reads a Snapshot of type named 'Person' before having a chance to map the Person class definition, the 'Person' type will be mapped to genericUnknownType.
Since 5.8.4, Javers logsWARNINGwhen UnknownType is created because Snapshots with UnknownType can't be properly deserialized fromJaversRepository.- Parameters:
packagesToScan- e.g. "my.company.domain.person, my.company.domain.finance"- Since:
- 2.3
-
scanTypeName
Register your class with @TypeNameannotation in order to use it in all kinds of JQL queries.
You can also usewithPackagesToScan(String)to scan all your classes.
Technically, this method is the convenient alias forJavers.getTypeMapping(Type)- Since:
- 1.4
-
registerValue
Registers a simple value type (seeValueType).
For example, values are: BigDecimal, LocalDateTime.
Use this method if can't use theValueannotation.
By default, Values are compared usingObject.equals(Object). You can provide externalequals()function by registering aCustomValueComparator. SeeregisterValue(Class, CustomValueComparator). -
registerValue
public <T> JaversBuilder registerValue(Class<T> valueClass, CustomValueComparator<T> customValueComparator) Registers aValueTypewith a custom comparator to be used instead ofObject.equals(Object).
For example, by default, BigDecimals are Values compared usingBigDecimal.equals(Object), sadly it isn't the correct mathematical equality:new BigDecimal("1.000").equals(new BigDecimal("1.00")) == falseIf you want to compare them in the right way — ignoring trailing zeros — register this comparator:JaversBuilder.javers() .registerValue(BigDecimal.class, new BigDecimalComparatorWithFixedEquals()) .build();- Type Parameters:
T- Value Type- Since:
- 3.3
- See Also:
-
registerValue
public <T> JaversBuilder registerValue(Class<T> valueClass, BiFunction<T, T, Boolean> equalsFunction, Function<T, String> toStringFunction) Lambda-style variant ofregisterValue(Class, CustomValueComparator).
For example, you can register the comparator for BigDecimals with fixed equals:Javers javers = JaversBuilder.javers() .registerValue(BigDecimal.class, (a, b) -> a.compareTo(b) == 0, a -> a.stripTrailingZeros().toString()) .build();- Type Parameters:
T- Value Type- Since:
- 5.8
- See Also:
-
registerValue
@Deprecated public <T> JaversBuilder registerValue(Class<T> valueClass, BiFunction<T, T, Boolean> equalsFunction) Deprecated.Deprecated, useregisterValue(Class, CustomValueComparator).
Since this comparator is not aligned withObject.hashCode(), it calculates incorrect results when a given Value is used in hashing context (when comparing Sets with Values or Maps with Values as keys).- See Also:
-
registerValueWithCustomToString
@Deprecated public <T> JaversBuilder registerValueWithCustomToString(Class<T> valueClass, Function<T, String> toStringFunction) Deprecated.Deprecated, useregisterValue(Class, CustomValueComparator).- Since:
- 3.7.6
- See Also:
-
registerIgnoredClass
Marks given class as ignored by JaVers.
Use this method as an alternative to theDiffIgnoreannotation.- See Also:
-
registerIgnoredClassesStrategy
A dynamic version ofregisterIgnoredClass(Class).
Registers a custom strategy for marking certain classes as ignored.
For example, you can ignore classes by package naming convention:Javers javers = JaversBuilder.javers() .registerIgnoredClassesStrategy(c -> c.getName().startsWith("com.ignore.me")) .build();Use this method as the alternative to theDiffIgnoreannotation or multiple calls ofregisterIgnoredClass(Class). -
registerValueTypeAdapter
Registers aValueTypeand its custom JSON TypeAdapter. Useful for ValueTypes when Gson's default representation isn't good enough. -
registerJsonAdvancedTypeAdapter
Registers an advanced variant of custom JSON TypeAdapter.- See Also:
-
registerValueGsonTypeAdapter
public JaversBuilder registerValueGsonTypeAdapter(Class valueType, com.google.gson.TypeAdapter nativeAdapter) RegistersValueTypeand its custom native Gson adapter.
Useful when you already have GsonTypeAdapters implemented.- See Also:
-
TypeAdapter
-
withTypeSafeValues
Switch on when you need a type safe serialization for heterogeneous collections like List, List<Object>.
Heterogeneous collections are collections which contains items of different types (or types unknown at compile time).
This approach is generally discouraged, prefer statically typed collections with exactly one type of items like List<String>.- Parameters:
typeSafeValues- default false- See Also:
-
withPrettyPrint
choose between JSON pretty or concise printing style, i.e. :- pretty:
{ "value": 5 } - concise:
{"value":5}
- Parameters:
prettyPrint- default true- See Also:
-
GsonBuilder.setPrettyPrinting()
- pretty:
-
registerEntities
-
registerValueObjects
-
withMappingStyle
Default style isMappingStyle.FIELD. -
withCommitIdGenerator
CommitIdGenerator.SYNCHRONIZED_SEQUENCE— for non-distributed applicationsCommitIdGenerator.RANDOM— for distributed applications -
withCustomCommitIdGenerator
-
withInitialChanges
The Initial Changes switch, enabled by default since Javers 6.0.
When the switch is enabled,Javers.compare(Object oldVersion, Object currentVersion)andJavers.findChanges(JqlQuery)generate additional set of Initial Changes for each property of a NewObject to capture its state.
Internally, Javers generates Initial Changes by comparing a virtual, empty object with a real NewObject.
For Primitives and Values an Initial Change is modeled asInitialValueChange(subtype ofValueChange) with null on left, and a property value on right.
For Collections, there are no specific subtypes to mark Initial Changes. So, for example, an Initial Change for a List is a regularListChangewith all elements from this list reflected asValueAdded.
In Javers Spring Boot starter you can disable Initial Value in `application.yml`:javers: initialChanges: false
-
withUsePrimitiveDefaults
The Use Primitive Defaults switch, enabled by default. Works only ifwithInitialChanges(boolean)orwithTerminalChanges(boolean)is enabled.
This switch affects howInitialValueChangeandTerminalValueChangeare calculated in the situation when a primitive property with a default value appears inNewObjector disappears inObjectRemoved.
When enabled, no changes are calculated if a primitive property with a default value (for example 0 for int) is compared to an added or removed property.
When disabled, Javers calculatesInitialValueChangeorTerminalValueChangewith null on one side and a primitive default value on the other side.
In Javers Spring Boot starter you can disable this switch in `application.yml`:javers: usePrimitiveDefaults: false
-
withNewObjectsSnapshot
Deprecated. -
withTerminalChanges
The Terminal Changes switch, enabled by default since Javers 6.0.
When the switch is enabled,Javers.compare(Object oldVersion, Object currentVersion)andJavers.findChanges(JqlQuery)generate additional set of Terminal Changes for each property of a Removed Object to capture its state.
Internally, Javers generates Terminal Changes by comparing a real Removed Object with a virtual, totally empty object.
In Javers Spring Boot starter you can disable Terminal Changes in `application.yml`:javers: terminalChanges: false
- Since:
- 6.0
- See Also:
-
withObjectAccessHook
-
registerCustomType
public <T> JaversBuilder registerCustomType(Class<T> customType, CustomPropertyComparator<T, ?> comparator) Registers aCustomPropertyComparatorfor a given class and maps this class toCustomType.
Custom Types are not easy to manage, use it as a last resort,
only for corner cases like comparing custom Collection types.
In most cases, it's better to customize the Javers' diff algorithm using much more simplerCustomValueComparator, seeregisterValue(Class, CustomValueComparator).- Type Parameters:
T- Custom Type- See Also:
-
registerCustomComparator
@Deprecated public <T> JaversBuilder registerCustomComparator(CustomPropertyComparator<T, ?> comparator, Class<T> customType) Deprecated. -
withListCompareAlgorithm
Choose between two algorithms for comparing list: ListCompareAlgorithm.SIMPLE or ListCompareAlgorithm.LEVENSHTEIN_DISTANCE.
Generally, we recommend using LEVENSHTEIN_DISTANCE, because it's smarter. However, it can be slow for long lists, so SIMPLE is enabled by default.
Refer to http://javers.org/documentation/diff-configuration/#list-algorithms for description of both algorithms- Parameters:
algorithm- ListCompareAlgorithm.SIMPLE is used by default
-
withDateTimeProvider
DateProvider providers current timestamp forCommit.getCommitDate().
By default, now() is used.
Overriding default dateProvider probably makes sense only in test environment. -
withPrettyPrintDateFormats
public JaversBuilder withPrettyPrintDateFormats(JaversCoreProperties.PrettyPrintDateFormats prettyPrintDateFormats) -
withProperties
-
registerCustomType(Class, CustomPropertyComparator)