Skip to content

Commit 384cfb2

Browse files
committed
DATAREDIS-425 - Update reference documentation, spelling fixes, minor improvements.
1 parent ebce1c2 commit 384cfb2

File tree

9 files changed

+76
-32
lines changed

9 files changed

+76
-32
lines changed

src/main/asciidoc/reference/redis-repositories.adoc

Lines changed: 30 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ To access domain entities stored in a Redis you can leverage repository support
1414
====
1515
[source,java]
1616
----
17-
@RedisHash("persons");
17+
@RedisHash("persons")
1818
public class Person {
1919
2020
@Id String id;
@@ -156,7 +156,7 @@ of Complex Type
156156
addresses.[work].city = "...
157157
|===
158158

159-
Mapping behavior can be customized by registering the according `Converter` in `CustomConversions`. Those converters can take care of converting from/to a single `byte[]` as well as `Map<String,byte[]>` whereas the first one is suitable for eg. converting one complex type to eg. a binary JSON representation that still uses the default mappings hash structure, whereas the second options offers full control over the resulting hash.
159+
Mapping behavior can be customized by registering the according `Converter` in `CustomConversions`. Those converters can take care of converting from/to a single `byte[]` as well as `Map<String,byte[]>` whereas the first one is suitable for eg. converting one complex type to eg. a binary JSON representation that still uses the default mappings hash structure. The second option offers full control over the resulting hash. Writing objects to a Redis hash will delete the content from the hash and re-create the whole hash, so not mapped data will be lost.
160160

161161
.Sample byte[] Converters
162162
====
@@ -306,15 +306,15 @@ public class ApplicationConfig {
306306

307307
[[redis.repositories.indexes]]
308308
== Secondary Indexes
309-
http://redis.io/topics/indexes[Secondary indexes] are used to enable lookup operations based on native redis structures. Values are written to the according indexes on every save and are removed when objects are deleted or <<redis.repositories.expirations,expire>>.
309+
http://redis.io/topics/indexes[Secondary indexes] are used to enable lookup operations based on native Redis structures. Values are written to the according indexes on every save and are removed when objects are deleted or <<redis.repositories.expirations,expire>>.
310310

311311
Given the sample `Person` entity we can create an index for _firstname_ by annotating the property with `@Indexed`.
312312

313313
.Annotation driven indexing
314314
====
315315
[source,java]
316316
----
317-
@RedisHash("persons");
317+
@RedisHash("persons")
318318
public class Person {
319319
320320
@Id String id;
@@ -349,7 +349,7 @@ Further more the programmatic setup allows to define indexes on map keys and lis
349349
====
350350
[source,java]
351351
----
352-
@RedisHash("persons");
352+
@RedisHash("persons")
353353
public class Person {
354354
355355
// ... other properties omitted
@@ -455,16 +455,19 @@ public class TimeToLiveOnMethod {
455455
The repository implementation ensures subscription to http://redis.io/topics/notifications[Redis keyspace notifications] via `RedisMessageListenerContainer`.
456456

457457
When the expiration is set to a positive value the according `EXPIRE` command is executed.
458-
Additionally to persisting the original, a _phantom_ copy is persisted in Redis and set to expire 5 minutes after the original one. This done to enable the Repository support to publish `RedisKeyExpiredEvent` holding the expired value via Springs `ApplicationEventPublisher` whenever a key expires even though the original values have already been gone.
458+
Additionally to persisting the original, a _phantom_ copy is persisted in Redis and set to expire 5 minutes after the original one. This is done to enable the Repository support to publish `RedisKeyExpiredEvent` holding the expired value via Springs `ApplicationEventPublisher` whenever a key expires even though the original values have already been gone. Expiry events
459+
will be received on all connected applications using Spring Data Redis repositories.
459460

460461
The `RedisKeyExpiredEvent` will hold a copy of the actually expired domain object as well as the key.
461462

462-
NOTE: The keyspace notification message listener will alter `notify-keyspace-events` settings in Redis if those are not already set. Existing settings will not be overridden so it is left to the user to set those up correctly when not leaving them empty.
463+
NOTE: The keyspace notification message listener will alter `notify-keyspace-events` settings in Redis if those are not already set. Existing settings will not be overridden, so it is left to the user to set those up correctly when not leaving them empty.
464+
465+
NOTE: Redis Pub/Sub messages are not persistent. If a key expires while the application is down the expiry event will not be processed which may lead to secondary indexes containing still references to the expired object.
463466

464467
[[redis.repositories.references]]
465468
== Persisting References
466-
Marking properties with `@Reference` allows to store a simple key reference instead of copying the all values into the hash itself.
467-
On loading from Redis references are resolved automatically and mapped back into the object.
469+
Marking properties with `@Reference` allows storing a simple key reference instead of copying values into the hash itself.
470+
On loading from Redis, references are resolved automatically and mapped back into the object.
468471

469472
.Sample Property Reference
470473
====
@@ -497,9 +500,12 @@ public interface PersonRepository extends CrudRepository<Person, String> {
497500
----
498501
====
499502

503+
500504
NOTE: Please make sure properties used in finder methods are set up for indexing.
501505

502-
Using derived finder methods might not always be sufficient to model the queries to execute. `RedisCallback` offers more control over the actual matching of index structures or even customly added ones. All it takes is providing a `RedisCallback` that returns a single or `Iterable` set of _id_ values.
506+
NOTE: Query methods for Redis repositories support only queries for entities and collections of entities with paging.
507+
508+
Using derived query methods might not always be sufficient to model the queries to execute. `RedisCallback` offers more control over the actual matching of index structures or even custom added ones. All it takes is providing a `RedisCallback` that returns a single or `Iterable` set of _id_ values.
503509

504510
.Sample finder using RedisCallback
505511
====
@@ -516,6 +522,20 @@ List<RedisSession> sessionsByUser = template.find(new RedisCallback<Set<byte[]>>
516522
----
517523
====
518524

525+
Here's an overview of the keywords supported for Redis and what a method containing that keyword essentially translates to.
526+
====
527+
528+
.Supported keywords inside method names
529+
[options = "header, autowidth"]
530+
|===============
531+
|Keyword|Sample|Redis snippet
532+
|`And`|`findByLastnameAndFirstname`|`SINTER …:firstname:rand …:lastname:al’thor`
533+
|`Or`|`findByLastnameOrFirstname`|`SUNION …:firstname:rand …:lastname:al’thor`
534+
|`Is,Equals`|`findByFirstname`,`findByFirstnameIs`,`findByFirstnameEquals`|`SINTER …:firstname:rand`
535+
|===============
536+
====
537+
538+
519539

520540

521541

src/main/java/org/springframework/data/redis/core/RedisKeyExpiredEvent.java

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,11 @@
2929
*/
3030
public class RedisKeyExpiredEvent<T> extends RedisKeyspaceEvent {
3131

32+
/**
33+
* Use {@literal UTF-8} as default charset.
34+
*/
35+
public static final Charset CHARSET = Charset.forName("UTF-8");
36+
3237
private final byte[][] args;
3338
private final Object value;
3439

@@ -62,7 +67,7 @@ public RedisKeyExpiredEvent(byte[] key, Object value) {
6267
public String getKeyspace() {
6368

6469
if (args.length >= 2) {
65-
return new String(args[0], Charset.forName("UTF-8"));
70+
return new String(args[0], CHARSET);
6671
}
6772

6873
return null;

src/main/java/org/springframework/data/redis/core/RedisQueryEngine.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ public RedisQueryEngine(CriteriaAccessor<RedisOperationChain> criteriaAccessor,
6666
* (non-Javadoc)
6767
* @see org.springframework.data.keyvalue.core.QueryEngine#execute(java.lang.Object, java.lang.Object, int, int, java.io.Serializable, java.lang.Class)
6868
*/
69+
@Override
6970
public <T> Collection<T> execute(final RedisOperationChain criteria, final Comparator<?> sort, final int offset,
7071
final int rows, final Serializable keyspace, Class<T> type) {
7172

src/main/java/org/springframework/data/redis/core/convert/Bucket.java

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,13 @@ public boolean isEmpty() {
9898
return data.isEmpty();
9999
}
100100

101+
/**
102+
* @return the number of key-value mappings of the {@link Bucket}.
103+
*/
104+
public int size() {
105+
return data.size();
106+
}
107+
101108
/**
102109
* @return never {@literal null}.
103110
*/
@@ -121,6 +128,12 @@ public Map<String, byte[]> asMap() {
121128
return Collections.unmodifiableMap(this.data);
122129
}
123130

131+
/**
132+
* Extracts a bucket containing key/value pairs with the {@code prefix}.
133+
*
134+
* @param prefix
135+
* @return
136+
*/
124137
public Bucket extract(String prefix) {
125138

126139
Bucket partial = new Bucket();

src/main/java/org/springframework/data/redis/core/convert/MappingRedisConverter.java

Lines changed: 22 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,7 @@ public MappingRedisConverter(RedisMappingContext mappingContext, IndexResolver i
144144
* (non-Javadoc)
145145
* @see org.springframework.data.convert.EntityReader#read(java.lang.Class, java.lang.Object)
146146
*/
147+
@Override
147148
public <R> R read(Class<R> type, final RedisData source) {
148149
return readInternal("", type, source);
149150
}
@@ -288,11 +289,11 @@ public void doWithAssociation(Association<KeyValuePersistentProperty> associatio
288289

289290
if (association.getInverse().isCollectionLike()) {
290291

291-
Collection<Object> target = CollectionFactory.createCollection(association.getInverse().getType(),
292-
association.getInverse().getComponentType(), 10);
293-
294292
Bucket bucket = source.getBucket().extract(currentPath + ".[");
295293

294+
Collection<Object> target = CollectionFactory.createCollection(association.getInverse().getType(),
295+
association.getInverse().getComponentType(), bucket.size());
296+
296297
for (Entry<String, byte[]> entry : bucket.entrySet()) {
297298

298299
String referenceKey = fromBytes(entry.getValue(), String.class);
@@ -333,6 +334,7 @@ public void doWithAssociation(Association<KeyValuePersistentProperty> associatio
333334
* (non-Javadoc)
334335
* @see org.springframework.data.convert.EntityWriter#write(java.lang.Object, java.lang.Object)
335336
*/
337+
@Override
336338
@SuppressWarnings({ "rawtypes" })
337339
public void write(Object source, final RedisData sink) {
338340

@@ -408,8 +410,8 @@ public void doWithPersistentProperty(KeyValuePersistentProperty persistentProper
408410
writeCollection(keyspace, propertyStringPath, (Collection<?>) accessor.getProperty(persistentProperty),
409411
persistentProperty.getTypeInformation().getComponentType(), sink);
410412
} else if (persistentProperty.isEntity()) {
411-
writeInternal(keyspace, propertyStringPath, accessor.getProperty(persistentProperty), persistentProperty
412-
.getTypeInformation().getActualType(), sink);
413+
writeInternal(keyspace, propertyStringPath, accessor.getProperty(persistentProperty),
414+
persistentProperty.getTypeInformation().getActualType(), sink);
413415
} else {
414416

415417
Object propertyValue = accessor.getProperty(persistentProperty);
@@ -442,8 +444,8 @@ public void doWithAssociation(Association<KeyValuePersistentProperty> associatio
442444

443445
if (association.getInverse().isCollectionLike()) {
444446

445-
KeyValuePersistentEntity<?> ref = mappingContext.getPersistentEntity(association.getInverse()
446-
.getTypeInformation().getComponentType().getActualType());
447+
KeyValuePersistentEntity<?> ref = mappingContext
448+
.getPersistentEntity(association.getInverse().getTypeInformation().getComponentType().getActualType());
447449

448450
String keyspace = ref.getKeySpace();
449451
String propertyStringPath = (!path.isEmpty() ? path + "." : "") + association.getInverse().getName();
@@ -458,8 +460,8 @@ public void doWithAssociation(Association<KeyValuePersistentProperty> associatio
458460

459461
} else {
460462

461-
KeyValuePersistentEntity<?> ref = mappingContext.getPersistentEntity(association.getInverse()
462-
.getTypeInformation());
463+
KeyValuePersistentEntity<?> ref = mappingContext
464+
.getPersistentEntity(association.getInverse().getTypeInformation());
463465
String keyspace = ref.getKeySpace();
464466

465467
Object refId = ref.getPropertyAccessor(refObject).getProperty(ref.getIdProperty());
@@ -535,10 +537,10 @@ private void writeToBucket(String path, Object value, RedisData sink) {
535537
private Collection<?> readCollectionOfSimpleTypes(String path, Class<?> collectionType, Class<?> valueType,
536538
RedisData source) {
537539

538-
Collection<Object> target = CollectionFactory.createCollection(collectionType, valueType, 10);
539-
540540
Bucket partial = source.getBucket().extract(path + ".[");
541541

542+
Collection<Object> target = CollectionFactory.createCollection(collectionType, valueType, partial.size());
543+
542544
for (byte[] value : partial.values()) {
543545
target.add(fromBytes(value, valueType));
544546
}
@@ -555,10 +557,10 @@ private Collection<?> readCollectionOfSimpleTypes(String path, Class<?> collecti
555557
private Collection<?> readCollectionOfComplexTypes(String path, Class<?> collectionType, Class<?> valueType,
556558
Bucket source) {
557559

558-
Collection<Object> target = CollectionFactory.createCollection(collectionType, valueType, 10);
559-
560560
Set<String> keys = source.extractAllKeysFor(path);
561561

562+
Collection<Object> target = CollectionFactory.createCollection(collectionType, valueType, keys.size());
563+
562564
for (String key : keys) {
563565

564566
Bucket elementData = source.extract(key);
@@ -583,6 +585,7 @@ private Collection<?> readCollectionOfComplexTypes(String path, Class<?> collect
583585
* @param sink
584586
*/
585587
private void writeMap(String keyspace, String path, Class<?> mapValueType, Map<?, ?> source, RedisData sink) {
588+
586589
if (CollectionUtils.isEmpty(source)) {
587590
return;
588591
}
@@ -614,10 +617,10 @@ private void writeMap(String keyspace, String path, Class<?> mapValueType, Map<?
614617
private Map<?, ?> readMapOfSimpleTypes(String path, Class<?> mapType, Class<?> keyType, Class<?> valueType,
615618
RedisData source) {
616619

617-
Map<Object, Object> target = CollectionFactory.createMap(mapType, 10);
618-
619620
Bucket partial = source.getBucket().extract(path + ".[");
620621

622+
Map<Object, Object> target = CollectionFactory.createMap(mapType, partial.size());
623+
621624
for (Entry<String, byte[]> entry : partial.entrySet()) {
622625

623626
String regex = "^(" + Pattern.quote(path) + "\\.\\[)(.*?)(\\])";
@@ -645,10 +648,10 @@ private void writeMap(String keyspace, String path, Class<?> mapValueType, Map<?
645648
private Map<?, ?> readMapOfComplexTypes(String path, Class<?> mapType, Class<?> keyType, Class<?> valueType,
646649
RedisData source) {
647650

648-
Map<Object, Object> target = CollectionFactory.createMap(mapType, 10);
649-
650651
Set<String> keys = source.getBucket().extractAllKeysFor(path);
651652

653+
Map<Object, Object> target = CollectionFactory.createMap(mapType, keys.size());
654+
652655
for (String key : keys) {
653656

654657
String regex = "^(" + Pattern.quote(path) + "\\.\\[)(.*?)(\\])";
@@ -723,6 +726,7 @@ public void setIndexResolver(IndexResolver indexResolver) {
723726
* (non-Javadoc)
724727
* @see org.springframework.data.convert.EntityConverter#getMappingContext()
725728
*/
729+
@Override
726730
public RedisMappingContext getMappingContext() {
727731
return this.mappingContext;
728732
}
@@ -731,6 +735,7 @@ public RedisMappingContext getMappingContext() {
731735
* (non-Javadoc)
732736
* @see org.springframework.data.convert.EntityConverter#getConversionService()
733737
*/
738+
@Override
734739
public ConversionService getConversionService() {
735740
return this.conversionService;
736741
}

src/main/java/org/springframework/data/redis/core/convert/RedisConverter.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
import org.springframework.data.keyvalue.core.mapping.KeyValuePersistentProperty;
2121

2222
/**
23-
* Redis sepcific {@link EntityConverter}.
23+
* Redis specific {@link EntityConverter}.
2424
*
2525
* @author Christoph Strobl
2626
* @since 1.7

src/main/java/org/springframework/data/redis/core/index/IndexDefinition.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
/**
2323
* {@link IndexDefinition} allow to set up a blueprint for creating secondary index structures in Redis. Setting up
2424
* conditions allows to define {@link Condition} that have to be passed in order to add a value to the index. This
25-
* allows to fine grained tune the I index structure. {@link IndexValueTransformer} gets applied to the raw value for
25+
* allows to fine grained tune the index structure. {@link IndexValueTransformer} gets applied to the raw value for
2626
* creating the actual index entry.
2727
*
2828
* @author Christoph Strobl

src/main/java/org/springframework/data/redis/repository/configuration/EnableRedisRepositories.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@
5353

5454
/**
5555
* Alias for the {@link #basePackages()} attribute. Allows for more concise annotation declarations e.g.:
56-
* {@code @EnableJpaRepositories("org.my.pkg")} instead of {@code @EnableJpaRepositories(basePackages="org.my.pkg")}.
56+
* {@code @EnableRedisRepositories("org.my.pkg")} instead of {@code @EnableRedisRepositories(basePackages="org.my.pkg")}.
5757
*/
5858
String[] value() default {};
5959

src/test/java/org/springframework/data/redis/repository/RedisRepositoryIntegrationTests.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ public void setUp() {
9393
* @see DATAREDIS-425
9494
*/
9595
@Test
96-
public void simpleFindSouldReturnEntitiesCorrectly() {
96+
public void simpleFindShouldReturnEntitiesCorrectly() {
9797

9898
Person rand = new Person();
9999
rand.firstname = "rand";

0 commit comments

Comments
 (0)