1

I am storing data in redis using JCA(java caching api) where key is String and value is Object which is JSON string. I have a requirement to perform partial update to cache value instead of retrieving cache value using key and then modify attribute and perform put operation with latest cache value

{
  "attribute1" : "value1",
   "attribute2 " : [
  {
   "attribute3" : "value3"
  }
]
}

Above is sample json format. As explained above is it possible to update value of attribute1 from value1 to value2 without geting cache value using key in redis

Anantha Pai
  • 13
  • 1
  • 3

2 Answers2

1

Assuming you are using JCache API (ie JSR-107), you can use Cache#invoke(K key, EntryProcessor<K,V,T> entryProcessor, Object... arguments) to perform an update in-place instead of get-then-put. According to EntryProcessor javadoc, Cache#invoke is executed atomically on the key, so you don't have to worry about concurrent modifications to the same cache entry.

  • My requirement is updating specific property of a POJO. Can I update property of POJO or attribute inside json Consider "employee" as a cache name which has key as employee id and value as Employee (id, name, age) POJO. is it possible to modify age of employee alone using employee id without using whole POJO – Anantha Pai Apr 29 '20 at 05:03
  • The `EntryProcessor` operates on a `MutableEntry` which has API methods for getting the existing value mapped to the key you are operating on and replacing it with a new one. If your `EntryProcessor` is aware of the new attribute value, your `EntryProcessor` can then get the existing value, update the attributes of interest and set the value. – Vassilis Bekiaris Apr 30 '20 at 15:23
0

You can use a Lua script, so that using the CJSON Lua library you update the item. I have shared a similar example on How to nest a list into a structure in Redis to reduce top level?

Not familiar with JCA, so not sure if your client would make it simple to send an EVAL command.

LeoMurillo
  • 6,048
  • 1
  • 19
  • 34
  • I am trying to execute HSET command but since I am using Redisson client with JCA, it doesnt have support to run native commands instead it provides RMap.fastput(). But it doesnt serve my purpose – Anantha Pai Apr 28 '20 at 16:05
  • I am able to run HSET command using HSET as below `conn.sync(StringCodec.INSTANCE, RedisCommands.HSET, "testmap", "age", "2");` This will helps to overwrite value of cache name "testmap" having key "age" to new value 2 But my purpose is if it is a json or POJO instead of string , Can I update property of POJO or attribute inside json Consider "testmap" has key as employee id and value as Employee (id, name, age). is it possible to modify age of employee alone using HSET – Anantha Pai Apr 29 '20 at 04:41
  • Prior to Redis4.0,the only method to work with JSON data inside of Redis was to use a Lua script through the cjson module.This partially solved the JSON problem although it still was a bottleneck and added the extra burden of learning Lua.Redis4.0+ have the ability to use modules.ReJSON is a module that provides a special datatype and direct manipulation commands.ReJSON stores the data in a binary format which removes the storage overhead from JSON,provides quicker access to elements without de-/re-serialization.https://redislabs.com/redis-best-practices/data-storage-patterns/json-storage/ – Anantha Pai Apr 29 '20 at 16:23
  • If you can do RedisCommands.HSET, you can do RedisCommands.EVAL_OBJECT or RedisCommands.EVAL_BOOLEAN (other flavors available). I encourage you to try Lua, it is simple. Use the example I provided in https://stackoverflow.com/questions/59979347/how-to-nest-a-list-into-a-structure-in-redis-to-reduce-top-level/59989914#59989914. Lua is the transactional language for Redis. Lua is to Redis what PL/SQL or T-SQL is to a SQL DB – LeoMurillo Apr 29 '20 at 19:20