Skip to content

Commit 7c43137

Browse files
javers-Redis text re-arrangement
javers-Redis text re-arrangement
1 parent e1d237b commit 7c43137

File tree

3 files changed

+106
-102
lines changed

3 files changed

+106
-102
lines changed

_includes/docs-sidebar.html

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -115,11 +115,11 @@
115115
<a {% if currentSubPage == 'repository-configuration' %}class='active'{% endif %}
116116
href="/documentation/repository-configuration">Configuration &mdash; Repository</a>
117117
<ul class="nav nav-stacked list-unstyled {% if page.submenu != 'repository-configuration' %} hidden {% endif %}">
118-
<li><a href="#choose-javers-repository">Choose JaversRepository</a></li>
119-
<li><a href="#redis-db">Redis</a></li>
118+
<li><a href="#choose-javers-repository">Choose JaversRepository</a></li>
120119
<li><a href="#mongodb-configuration">MongoDB</a></li>
121120
<li><a href="#sql-databases">SQL databases</a></li>
122121
<li><a href="#connection-provider">&nbsp; &nbsp;ConnectionProvider</a></li>
122+
<li><a href="#redis-db">Redis</a></li>
123123
<li><a href="#custom-json-serialization">Custom JSON serialization</a>
124124
<li><a href="#json-type-adapters">&nbsp; &nbsp;JSON TypeAdapters</a>
125125
<li><a href="#json-type-adapter-example">&nbsp; &nbsp;JSON TypeAdapter Example</a>

documentation/repository-configuration/index.md

Lines changed: 96 additions & 92 deletions
Original file line numberDiff line numberDiff line change
@@ -36,98 +36,6 @@ almost fully compatible with MongoDB.
3636
[Spring Boot starters for Spring Data](/documentation/spring-boot-integration/)
3737
and let them automatically configure and boot a JaVers instance with proper JaversRepository implementation.
3838

39-
<h2 id="redis-db">Redis</h2>
40-
41-
**Redis persistence overview**<br/>
42-
43-
When storing JaVers snapshots in Redis, selecting the right persistence model is essential for ensuring data durability and performance. Redis offers two main persistence models:
44-
45-
- RDB (Redis Database) - Periodically saves the dataset to disk. This is less resource-intensive because it doesn't constantly write to disk but instead saves the state at certain intervals.
46-
- AOF (Append Only File) - Logs every write operation to disk as it happens. In case of a crash, Redis can replay the log to restore the data.
47-
48-
Redis allows using both RDB and AOF simultaneously. This provides the advantage of faster recovery through RDB snapshots while maintaining high durability with AOF. Depending on the system's criticality, you may want to consider enabling both for your JaVers snapshot storage.
49-
50-
For more information, check the [official Redis documentation](https://redis.io/docs/latest/operate/oss_and_stack/management/persistence/).
51-
52-
53-
**Dependency**<br/>
54-
Add `javers-persistence-redis` module to your classpath:
55-
56-
_Maven_<br/>
57-
58-
```
59-
<dependency>
60-
<groupId>org.javers</groupId>
61-
<artifactId>javers-persistence-redis</artifactId>
62-
<version>{{site.javers_current_version}}</version>
63-
</dependency>
64-
```
65-
66-
_Gradle (short)_<br/>
67-
68-
```
69-
implementation 'org.javers:javers-persistence-redis:{{site.javers_current_version}}'
70-
```
71-
72-
Check
73-
[Maven Central](https://central.sonatype.com/artifact/org.javers/javers-persistence-redis/{{site.javers_current_version}}/versions)
74-
for other build tools snippets.
75-
76-
<h3>Overview</h3>
77-
78-
The idea of configuring `JaversRedisRepository` is simple, just provide a working Jedis (Java client for Redis). You can setup `JaversRedisRepository` as follows:
79-
80-
```java
81-
import org.javers.repository.redis.JaversRedisRepository;
82-
import redis.clients.jedis.JedisPool;
83-
...
84-
85-
private static final String REDIS_HOST = "localhost";
86-
private static final int REDIS_PORT = 6379;
87-
private static final Duration REDIS_KEY_EXPIRATION_TIME = Duration.ofSeconds(3600);
88-
89-
90-
final var jedisPool = new JedisPool();
91-
final var javersRedisRepository = new JaversRedisRepository(jedisPool, REDIS_KEY_EXPIRATION_TIME);
92-
final var javers = JaversBuilder.javers().registerJaversRepository(javersRedisRepository).build();
93-
```
94-
95-
<h3>Schema</h3>
96-
JaVers creates several key-value pairs in Redis, with main keys being:
97-
98-
- `jv_head_id` — A `String` that holds the value of the last `CommitId`.
99-
- `jv_snapshots_keys` — A `Set` that contains keys, where each key is a reference to another key of type `List`. These lists contain snapshots for specific entities and their properties.
100-
- `jv_snapshots_keys:<Entity Name>` — Domain-specific sets pointing to lists containing snapshots for specific objects of that entity type.
101-
102-
<h3>Handling Redis Key Expiration</h3>
103-
104-
In Redis, when a key expires, it is automatically removed from the database. However, additional cleanup may be required if the expired key is referenced in other structures, such as sets.
105-
106-
**CdoSnapshotKeyExpireListener**
107-
108-
The `CdoSnapshotKeyExpireListener` is an event listener designed to handle key expiration events in Redis. Its primary responsibility is to ensure that expired key entries are removed from all relevant sets.
109-
110-
When an instance of `JaversRedisRepository` is created, it subscribes to keyspace events with the pattern `__key*__:jv_snapshots:*`. This subscription allows the `CdoSnapshotKeyExpireListener` to process key expiration events as they occur.
111-
112-
Upon receiving a key expiration event, the `CdoSnapshotKeyExpireListener` identifies the expired key and removes its entries from all relevant sets, such as `jv_snapshots_keys` and `jv_snapshots_keys:<Entity Name>`.
113-
114-
**Expired Keys Cleanup**
115-
116-
A significant challenge arises if Redis keys expire when there is no active `CdoSnapshotKeyExpireListener` running. In this scenario, expired key entries will remain in the sets, leading to potential data inconsistencies.
117-
118-
To address this challenge, we have introduced the public method `cleanExpiredSnapshotsKeysSets` in JaversRedisRepository that can be called to perform the necessary cleanup. This ensures that expired keys are properly removed from all relevant sets, even if the listener is not active at the time of expiration.
119-
120-
<h3>Integrating JaversRedisRepository with JPA (Hibernate)</h3>
121-
122-
The `JaversRedisRepository` can be seamlessly integrated with existing JPA repositories, enabling you to store JaVers audit data in Redis while continuing to use your JPA entities and repositories for application data.
123-
124-
However, when working with Hibernate, it’s common for entities to be wrapped in proxies. To ensure proper handling of these proxies, you need to configure the `HibernateUnproxyObjectAccessHook` in your application. This can be done by setting the following property in your application configuration file:
125-
```yaml
126-
javers:
127-
objectAccessHook: org.javers.hibernate.integration.HibernateUnproxyObjectAccessHook
128-
```
129-
This configuration ensures that JaVers can unproxy Hibernate entities effectively, allowing audit logging to work seamlessly with Redis and JPA.
130-
13139
<h2 id="mongodb-configuration">MongoDB</h2>
13240
**Dependency**<br/>
13341
If you’re using MongoDB, choose `MongoRepository`.
@@ -313,6 +221,102 @@ JaVers has a basic schema-create implementation.
313221
If a table is missing, JaVers simply creates it, together with a sequence and indexes.
314222
There’s no schema-update, so if you drop a column, index or sequence, it wouldn’t be recreated automatically.
315223

224+
225+
<h2 id="redis-db">Redis</h2>
226+
227+
**Redis persistence overview**<br/>
228+
229+
When storing JaVers snapshots in Redis, selecting the right persistence model is essential for ensuring data durability and performance. Redis offers two main persistence models:
230+
231+
- RDB (Redis Database) - Periodically saves the dataset to disk. This is less resource-intensive because it doesn't constantly write to disk but instead saves the state at certain intervals.
232+
- AOF (Append Only File) - Logs every write operation to disk as it happens. In case of a crash, Redis can replay the log to restore the data.
233+
234+
Redis allows using both RDB and AOF simultaneously. This provides the advantage of faster recovery through RDB snapshots while maintaining high durability with AOF. Depending on the system's criticality, you may want to consider enabling both for your JaVers snapshot storage.
235+
236+
For more information, check the [official Redis documentation](https://redis.io/docs/latest/operate/oss_and_stack/management/persistence/).
237+
238+
239+
**Dependency**<br/>
240+
Add `javers-persistence-redis` module to your classpath:
241+
242+
_Maven_<br/>
243+
244+
```
245+
<dependency>
246+
<groupId>org.javers</groupId>
247+
<artifactId>javers-persistence-redis</artifactId>
248+
<version>{{site.javers_current_version}}</version>
249+
</dependency>
250+
```
251+
252+
_Gradle (short)_<br/>
253+
254+
```
255+
implementation 'org.javers:javers-persistence-redis:{{site.javers_current_version}}'
256+
```
257+
258+
Check
259+
[Maven Central](https://central.sonatype.com/artifact/org.javers/javers-persistence-redis/{{site.javers_current_version}}/versions)
260+
for other build tools snippets.
261+
262+
<h3>Overview</h3>
263+
264+
The idea of configuring `JaversRedisRepository` is simple, just provide a working Jedis (Java client for Redis). You can setup `JaversRedisRepository` as follows:
265+
266+
```java
267+
import org.javers.repository.redis.JaversRedisRepository;
268+
import redis.clients.jedis.JedisPool;
269+
...
270+
271+
private static final String REDIS_HOST = "localhost";
272+
private static final int REDIS_PORT = 6379;
273+
private static final Duration REDIS_KEY_EXPIRATION_TIME = Duration.ofSeconds(3600);
274+
275+
276+
final var jedisPool = new JedisPool();
277+
final var javersRedisRepository = new JaversRedisRepository(jedisPool, REDIS_KEY_EXPIRATION_TIME);
278+
final var javers = JaversBuilder.javers().registerJaversRepository(javersRedisRepository).build();
279+
```
280+
281+
<h3>Schema</h3>
282+
JaVers creates several key-value pairs in Redis, with main keys being:
283+
284+
- `jv_head_id` — A `String` that holds the value of the last `CommitId`.
285+
- `jv_snapshots_keys` — A `Set` that contains keys, where each key is a reference to another key of type `List`. These lists contain snapshots for specific entities and their properties.
286+
- `jv_snapshots_keys:<Entity Name>` — Domain-specific sets pointing to lists containing snapshots for specific objects of that entity type.
287+
288+
<h3>Handling Redis Key Expiration</h3>
289+
290+
In Redis, when a key expires, it is automatically removed from the database. However, additional cleanup may be required if the expired key is referenced in other structures, such as sets.
291+
292+
**CdoSnapshotKeyExpireListener**
293+
294+
The `CdoSnapshotKeyExpireListener` is an event listener designed to handle key expiration events in Redis. Its primary responsibility is to ensure that expired key entries are removed from all relevant sets.
295+
296+
When an instance of `JaversRedisRepository` is created, it subscribes to keyspace events with the pattern `__key*__:jv_snapshots:*`. This subscription allows the `CdoSnapshotKeyExpireListener` to process key expiration events as they occur.
297+
298+
Upon receiving a key expiration event, the `CdoSnapshotKeyExpireListener` identifies the expired key and removes its entries from all relevant sets, such as `jv_snapshots_keys` and `jv_snapshots_keys:<Entity Name>`.
299+
300+
**Expired Keys Cleanup**
301+
302+
A significant challenge arises if Redis keys expire when there is no active `CdoSnapshotKeyExpireListener` running. In this scenario, expired key entries will remain in the sets, leading to potential data inconsistencies.
303+
304+
To address this challenge, we have introduced the public method `cleanExpiredSnapshotsKeysSets` in JaversRedisRepository that can be called to perform the necessary cleanup. This ensures that expired keys are properly removed from all relevant sets, even if the listener is not active at the time of expiration.
305+
306+
<h3>Integrating JaversRedisRepository with JPA (Hibernate)</h3>
307+
308+
The `JaversRedisRepository` can be seamlessly integrated with existing JPA repositories, enabling you to store JaVers audit data in Redis while continuing to use your JPA entities and repositories for application data.
309+
310+
However, when working with Hibernate, it’s common for entities to be wrapped in proxies. To ensure proper handling of these proxies, you need to configure the `HibernateUnproxyObjectAccessHook` in your application. This can be done by setting the following property in your application configuration file:
311+
312+
```yaml
313+
javers:
314+
objectAccessHook: org.javers.hibernate.integration.HibernateUnproxyObjectAccessHook
315+
```
316+
317+
This configuration ensures that JaVers can unproxy Hibernate entities effectively, allowing audit logging to work seamlessly with Redis and JPA.
318+
319+
316320
<h2 id="custom-json-serialization">Custom JSON serialization</h2>
317321
JaVers is meant to support various persistence stores (MongoDB, SQL)
318322
for any kind of your data. Hence, we use JSON format to serialize your objects in a JaversRepository.

documentation/spring-boot-integration/index.md

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -22,13 +22,6 @@ There are two Javers Spring Boot starters:
2222

2323
<h2 id="get-javers-starters">Get a Javers Spring Boot starter</h2>
2424

25-
### The Redis starter ###
26-
Add the Javers Spring Boot starter for Redis to your classpath:
27-
28-
```groovy
29-
implementation 'org.javers:javers-spring-boot-starter-redis:{{site.javers_current_version}}'
30-
```
31-
3225
### The MongoDB starter ###
3326
Add the Javers Spring Boot starter for MongoDB to your classpath:
3427

@@ -46,6 +39,13 @@ implementation 'org.javers:javers-spring-boot-starter-sql:{{site.javers_current_
4639
Check [Maven Central](https://central.sonatype.com/artifact/org.javers/javers-spring-boot-starter-sql/{{site.javers_current_version}}/versions)
4740
for other build tool snippets.
4841

42+
### The Redis starter ###
43+
Add the Javers Spring Boot starter for Redis to your classpath:
44+
45+
```groovy
46+
implementation 'org.javers:javers-spring-boot-starter-redis:{{site.javers_current_version}}'
47+
```
48+
4949
<h2 id="starters-auto-configuration">Spring Boot Auto-configuration</h2>
5050

5151
Thanks to the Spring Boot magic, Javers auto-configuration
@@ -61,9 +61,9 @@ according to your application configuration. That is:
6161

6262
Check the complete list of Javers beans added to your Spring Context:
6363

64-
* for Redis: [JaversRedisAutoConfiguration.java](https://github.com/javers/javers/blob/master/javers-spring-boot-starter-redis/src/main/java/org/javers/spring/boot/redis/JaversRedisAutoConfiguration.java)
6564
* for MongoDB: [JaversMongoAutoConfiguration.java](https://github.com/javers/javers/blob/master/javers-spring-boot-starter-mongo/src/main/java/org/javers/spring/boot/mongo/JaversMongoAutoConfiguration.java),
6665
* for SQL: [JaversSqlAutoConfiguration.java](https://github.com/javers/javers/blob/master/javers-spring-boot-starter-sql/src/main/java/org/javers/spring/boot/sql/JaversSqlAutoConfiguration.java).
66+
* for Redis: [JaversRedisAutoConfiguration.java](https://github.com/javers/javers/blob/master/javers-spring-boot-starter-redis/src/main/java/org/javers/spring/boot/redis/JaversRedisAutoConfiguration.java)
6767

6868
<h2 id="customizing-auto-configuration">Customizing the Auto-configuration</h2>
6969

0 commit comments

Comments
 (0)