We now allow partial update of domain types via PartialUpdate. The according expiration times and secondary index structures are updated accordingly.
In some cases it is not necessary to load and rewrite the entire entity just to set a new value within it. A session timestamp for last active time might be such a scenario where you just want to alter one property.
`PartialUpdate` allows to define `set`, `delete` actions on existing objects while taking care of updating potential expiration times of the entity itself as well as index structures.
.Sample Partial Update
====
[source,java]
----
PartialUpdate<Person> update = new PartialUpdate<Person>("e2c7dcee", Person.class)
.set("firstname", "mat") <1>
.set("address.city", "emond's field") <2>
.del("age"); <3>
template.update(update);
update = new PartialUpdate<Person>("e2c7dcee", Person.class)
.set("address", new Address("caemlyn", "andor")) <4>
.set("attributes", singletonMap("eye-color", "grey")); <5>
template.update(update);
update = new PartialUpdate<Person>("e2c7dcee", Person.class)
.refreshTtl(true); <6>
.set("expiration", 1000);
template.update(update);
----
<1> Set the simple property _firstname_ to _mat_
<2> Set the simple property _address.city_ to _emond's field_ without having to pass in the entire object. This does not work when a custom conversion is registered.
<3> Remove the property _age_.
<4> Set complex property _address_.
<5> Set a map/collection of values removes the previously existing map/collection and replaces the values with the given ones.
<6> Automatically update the server expiration time when altering time to live.
====
NOTE: Updating complex objects as well as map/collection structures requires further interaction with Redis to determine existing values which means that it might turn out that rewriting the entire entity might be faster.
Original pull request: #191.
Set EnableRedisRepositories.enableKeyspaceEvents default to OFF. Expiry notifications require to opt-in. Add JavaDoc. Add documentation for delayed/disabled event listener. Fix spelling. Use property value instead of attribute on RedisKeyValueAdapter bean definition. Remove trailing white spaces.
Original pull request: #193.
We now allow more fine grained setup for usage of Redis keyspace events. This can be done programmatically via the RedisKeyValueAdapter or using `@EnableRedisRepositories.enableKeyspaceEvents`.
Original pull request: #193.
RedisGeoCommands now take and return Spring Data domain types like Distance and GeoResults.
Updated JavaDoc and Reference documentation.
Added and updated author and license headers.
Fixed minor formatting and code style issues.
Original Pulll Request: #187
Return zero (0) in getAndSet to prevent NullPointerExceptions. Remove trailing whitespace. Add tests for existing methods. Simplify tests.
Original pull request: #182.
We now throw DataRetrievalFailureException in case of get() when the underlying key storing the value of an AtomicInteger, AtomicLong or AtomicDouble is removed from Redis.
Original pull request: #182.
Added FasterXML Jackson `ObjectMapper` based `HashMapper` implementation that allows flattening.
```java
class Person {
String firstname;
String lastname;
Address address;
}
class Address {
String city;
String country;
}
```
```bash
firstname:Jon
lastname:Snow
address:{ city : Castle Black, country : The North }
firstname:Jon
lastname:Snow
address.city:Castle Black
address.country:The North
```
Original pull request: #197.
Do not destroy RedisConnectionFactory which is likely managed outside of RedisKeyValueAdapter.
This change makes sure to retain a working connection factory while shutting down message listeners as those try to unsubscribe on shutdown.
Original Pull Request: #195
Rename ConvertingHashMapper to ObjectHashMapper. Add fromHash with type to avoid casting. Add JavaDoc documentation to HashMapper. Add hash mapping to reference documentation.
Original pull request: #194.
We now support mapping of simple and complex types to Redis HASH structures applying the same structure as the Repository support. This allows Object to hash Mapping and its direct usage via RedisTemplate without the need of explicitly having to use the repository abstraction.
Original pull request: #194.
We now pick up the ClassLoader from the ApplicationContext and use the latter as default in RedisTemplate for initializing the JdkSerializationRedisSerializer. We only do this in case the default serializer has not been set explicitly.
Original pull request: #192.
Add missing author tag. Minor reformatting. Explicitly set default SSL options and add test to verify default SSL options. Enhance JavaDoc.
Original pull request: #180.
LettuceConnectionFactory now supports verifyPeer and startTls options for Redis Standalone usage.
Original pull request: #180.
CLA: 166820160311101157 (Balázs Németh)
We now allow constructing JdkSerializationRedisSerializer using an own class loader and by specifying custom converters.
Using an own class-loader: new JdkSerializationRedisSerializer(classLoader)
Using own converters (Serializer/Deserializer): new JdkSerializationRedisSerializer(new SerializingConverter(), new DeserializingConverter(new DefaultDeserializer(classLoader)))
Original Pull Request: #179
Update jedis driver to 2.8.1. Use binary method for SSCAN and implement ZSCAN and HSCAN methods. Move ScanOptions to ScanParams conversion to JedisConverters.
Original Pull Request: #178
Add author and getter method for SSL property. Apply formatting. Create test to validate SSL setting is set correctly in the lettuce driver.
Original pull request: #177.
We now preserve the item order when converting list elements. This does not mean that we place elements at the exact position retrieved from the store but rather maintain their order based on the index value.
Additionally applied some documentation polishing and cluster tests.
Original Pull Request: #156
We ship converters for JSR-310 types (LocalDate/Time, ZonedDateTime, Period, Duration and ZoneId) to map between UTF-8-encoded byte[] and JDK 8 date/time types.
We also export Redis Repositories in a CDI environment. Repositories can be injected using @Inject. The CDI extension requires at least RedisOperations to be provided. Other beans like RedisKeyValueAdapter and RedisKeyValueTemplate can be provided by the user. If no RedisKeyValueAdapter/RedisKeyValueTemplate beans are found, the CDI extension creates own managed instances.
Original Pull Request: #156
- Add a composite IndexResolver implementation that iterates over a given collection of delegate IndexResolver instances and collects IndexedData from those.
- Break up cycle involving ReferenceResolver and let the resolver just returns the raw hash.
- Remove IndexType and use dedicated classes for index definitions.
- Fix pagination error and follow up to changes introduced via DATAKV-123.
Original Pull Request: #156
This commit adds support for distinguishing between
the property path that is being indexed and the
name of the index that should be used.
This is useful when you do not want the property
path and index name to be the same. For example,
if you want to use Spel expressions, it may not be
possible to use the path as the name of the index.
Original PR #160
We now enable storing domain object as a flat Redis 'HASH' and maintain additional 'SET' structures to enable finder operations on simple properties.
@RedisHash("persons");
class Person {
@id String id;
@Indexed String firstname;
String lastname;
Map<String, String> attributes;
City city;
@Reference Person mother;
}
The above is stored in the HASH with key 'persons:1' as
_class = org.example.Person
id = 1
firstname = rand
lastname = al’thor
attributes.[eye-color] = grey
attributes.[hair-color] = red
city.name = emond's field
city.region = two rivers
mother = persons:2
Complex types are flattened out to their full property path for each of the values provided. If the properties actual value type does not match the declared one the '_class' type hint is added to the entry.
city._class = CityInAndor.class
city.name = emond's field
city.region = two rivers
city.country = andor
Map and Collection like structures are stored with their key/index values as part of the property path. If the map/collection value type does not match the actutal objects one the '_class' type hint is added to the entry.
list.[0]._class = DomainType.class
list.[0].property1 = ...
map.[key-1]._class = DomainType.class
map.[key-1].property1 = ...
Properties marked with '@Reference' are stored as semantic references by just storing the key to the referenced object 'HASH' instead of embedding its values.
mother = persons:2
Please note that referenced objects are not transitively updated/saved and that lazy loading of references will be part of future development.
A 'save' operation therefore executes the following:
# flatten domain type and add as hash
HMSET persons:1 id 1 firstname rand …
# add the newly inserted entry to the list of all entries of that type
SADD persons 1
# index the firstname for finder lookup
SADD persons.firstname:rand 1
Simple finder operation like 'findByFirstname' use 'SINTER' to find matching
SINTER persons.firstname:rand
HGETALL persons:1
Besides resolving an index via the '@Index' annotation we also allow to add custom configuration via the 'indexConfiguration' attribute of '@EnableRedisRepositories'.
@Configuration
@EnableRedisRepositories(indexConfiguration = CustomIndexConfiguration.class)
class Config { }
static class CustomIndexConfiguration extends IndexConfiguration {
@Override
protected Iterable<RedisIndexDefinition> initialConfiguration() {
return Arrays.asList(
new SimpleIndexDefinition("persons", "lastname"),
);
}
}
The '@TimeToLive' annotation allows to define a property or method providing an expiration time when storing the key in redis.
@RedisHash
class Person {
@Id String id;
@TimeToLive Long ttl;
}
Original Pull Request: #156
Remove guards and use native driver api for pexpire and psetex which is available in the current jedis distribution.
Original Pull Request: #175
CLA: 165820160303082625 (Milan Agatonovic)
Add DecoratedRedisConnection interface to unwrap decorated connections. When running on Redis Cluster, use keys/del instead of lua script because cluster connections do not support lua script execution.
Original pull request: #173.
We now guard multi/exec blocks by checking the connection type. This allows to skip those commands when running in cluster.
Original pull request: #173.
We moved away from returning raw map types and now return dedicated objects for command executions in cluster environment. This allows to maintain node information and collecting results from each and every callback. MGET now returns values according to the key position.
Additionally we now prefix info commands in the cluster with the nodes host:port.
Original pull request: #174.
Add ClientResources to LettuceConnectionFactory. Add TestClientResources for managed resources during tests and reuse ClientResources as much as possible in tests.
Original Pull Request: #169
Extend JavaDoc documentation. Spelling fixes. Add Expiration.from factory method to create Expiration from all available time units.
Original pull request: #170.
We now support EX/PX and NX/XX arguments along with the SET command for both xetorthio/jedis and mp911de/lettuce.
Jedis 2.8 does not support all combinations of EX/PX and NX/XX. To work around those limitations we delegate to the according set methods to execute related commands or fail fast if there is no way for delegation.
Original pull request: #170.