Mastering JaVers: Java Object Versioning Made Simple
This article introduces JaVers, an open‑source Java framework for object versioning, outlines its key use cases, evaluates its strengths and weaknesses, and provides practical code examples for comparison, committing changes, and persisting audit data across various databases.
Introduction
JaVers is an open‑source Java version‑control framework that helps developers manage and track object versions, offering simple APIs for creating, modifying, deleting, and auditing objects in web, desktop, or mobile applications.
Typical Use Cases
Version control of domain objects to track modification history.
Transaction management with a straightforward API for handling operations and exceptions.
Conflict resolution when multiple developers modify the same object concurrently.
Database migration by moving objects from older to newer versions without manual scripts.
Advantages
Easy to learn with a gentle learning curve.
Rich feature set including versioning, transaction handling, conflict merging, and migration.
Highly extensible, allowing custom extensions.
Active open‑source community providing support.
Disadvantages
Higher technical barrier for beginners due to its complexity.
Potential impact on database performance because of extensive historical data storage.
Possible data redundancy from storing full object histories, which may waste storage in some scenarios.
Example Code
Dependency configuration (Maven):
<code><dependency>
<groupId>org.javers</groupId>
<artifactId>javers-core</artifactId>
<version>7.3.6</version>
</dependency>
<dependency>
<groupId>org.javers</groupId>
<artifactId>javers-persistence-sql</artifactId>
<version>7.3.6</version>
</dependency></code>Comparing two objects:
<code>Person p1 = new Person("1", "junly", 22);
Person p2 = new Person("2", "rose", 22);
Javers javers = JaversBuilder.javers().build();
Diff diff = javers.compare(p1, p2);
if (diff.hasChanges()) {
diff.getChanges().forEach(change -> System.out.println(change.toString()));
}
System.out.println(diff.prettyPrint());</code>Committing objects for versioning:
<code>public static void main(String[] args) {
Javers javers = JaversBuilder.javers().build();
Person p1 = new Person("1", "junly", 22);
javers.commit("u1", p1);
Person p2 = new Person("1", "junly", 20);
javers.commit("u1", p2);
Person p3 = new Person("1", "tom", 22);
javers.commit("u1", p3);
JqlQuery query = QueryBuilder.byInstanceId("1", Person.class).build();
List<Shadow<Object>> shadows = javers.findShadows(query);
shadows.forEach(s -> System.out.println(s.get()));
List<CdoSnapshot> snapshots = javers.findSnapshots(query);
snapshots.forEach(s -> System.out.println(s.getChanged()));
Changes changes = javers.findChanges(query);
changes.forEach(c -> System.out.println(c.toString()));
}</code>Persistence Options
JaVers supports two persistence modes: in‑memory and database storage. It works with databases such as H2, MySQL, PostgreSQL, Oracle, SQL Server, and MongoDB. Example configuration for MySQL:
<code>JaversRepository javersRepository = SqlRepositoryBuilder.sqlRepository()
.withConnectionProvider(() -> getConnection())
.withDialect(DialectName.MYSQL)
.build();
Javers javers = JaversBuilder.javers()
.registerJaversRepository(javersRepository)
.build();</code>Using JQL queries, developers can retrieve detailed historical data as needed.
Conclusion
JaVers provides comprehensive capabilities for object comparison, version control, transaction management, conflict resolution, and database migration, with strong extensibility that allows developers to tailor the framework to specific requirements.
macrozheng
Dedicated to Java tech sharing and dissecting top open-source projects. Topics include Spring Boot, Spring Cloud, Docker, Kubernetes and more. Author’s GitHub project “mall” has 50K+ stars.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.