I am using RedisTemplate and I'm putting a string as a key. Will there be any advantage using JdkSerializationRedisSerializer for the keySerializer of the redis template, or any disadvantages using StringRedisSerializer for keySerializer, If I'm only using strings for the key?
Related
I am learning Spring Data Redis, and need some help with the RedisTemplate:
Looking at the javadoc of RedisTemplate, I can see the following serializer setters:
public void setKeySerializer(RedisSerializer<?> serializer)
public void setHashKeySerializer(RedisSerializer<?> hashKeySerializer)
public void setValueSerializer(RedisSerializer<?> serializer)
public void setHashValueSerializer(RedisSerializer<?> hashValueSerializer)
I wonder when is the framework using which of the serializers? What's the difference between the ones with 'Hash" and the ones without?
In order to use Redis Spring Data Repositories where secondary index matching is supported, I should provide a RedisTemplate with default setting and name it redisTemplate, right?
What happens when I need both pub/sub with custom message body format (say json) and Spring Data repository in the same app? Should I define a default RedisTemplate (like point 2) for the repositories and create my own configuration class to build the message publisher instead of registering another RedisTemplate with Jackson2JsonRedisSerializer?
Thanks in advance for the help!
As the title, i found jedis support pop multiple elements jedis commands source code
I reviewed spring-data-redis project's source code, and cant't find any method support this.
How could i do for pop multiple elements in spring data redis?
RedisSetCommands#spop(key, count) and its counterpart in SetOperations is currently not implemented in Spring Data Redis. I've opened DATAREDIS-668 to add support for the count option.
Meanwhile you can use RedisTemplate#execute to obtain the value via the underlying connection, having the template take care of resource handling.
redisTemplate.execute((RedisCallback<Set<String>>) conn -> {
Jedis jedis = (Jedis) conn.getNativeConnection(); // access native driver
return jedis.spop(key, count);
});
You can use SetOperations#pop to pop a random element. Just define a RedisTemplate
<bean id="jedisConnFactory"
class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory"
p:use-pool="true"/>
<bean id="redisTemplate"
class="org.springframework.data.redis.core.RedisTemplate"
p:connection-factory-ref="jedisConnFactory"/>
And then you can inject it as SetOperations
#Resource(name="redisTemplate")
private SetOperations<String, String> operation;
You can find other RedisTemplate views at Working with Objects through RedisTemplate
You can also use JDK collection interfaces, see Support Classes
I try to use database encryption for single fields with Spring and Jpa (Hibernate). Here is the part of the Entity:
#ColumnTransformer(
read="AES_DECRYPT(UNHEX(lastname), UNHEX(SHA2('secret', 512)))",
write="HEX(AES_ENCRYPT(?, UNHEX(SHA2('secret', 512))))"
)
private String lastname;
This uses Mysql-functions to encrypt and decrypt my field, so I do not have to care in Java.
My problem is that I cannot hardcode the passphrase in my Java-Code, but Java-Annotations only allow non-dynamic final Strings as params. How do I use a spring application property to replace the passphrase 'secret'?
I cannot use a Jpa-Converter, because I want to be able to filter and sort by lastname. I also tried to subclass MySQL5InnoDBDialect and register a StandardSQLFunction, but that does not work conceptually with #ColumnTransformer because these functions are registered in the context of JPA, not SQL. I also thought of programmatically manipulating the hibernate config before it is used to create the EntityManagerFactory, but I do not know how to do that. Any help appreciated.
I am new to Redis and want to implement it with my existing spring application.
My question is to use different redisTemplate with same keys to store different types of values.
For e.g.
I have redisTemplate1 and redisTemplate2 beans defined in spring, like.
<bean id="redisTemplate1" class ="org.springframework.data.redis.core.RedisTemplate" p:connection-factory-ref ="connectionFactory" />
<bean id="redisTemplate2" class ="org.springframework.data.redis.core.RedisTemplate" p:connection-factory-ref ="connectionFactory" />
In java file to my service, I have created two different data structure using these two redis templates.
#Autowired
#Qualifier(value = "redisTemplate1")
private RedisTemplate<String, Student> redisTemplate1;
#Autowired
#Qualifier(value = "redisTemplate2")
private RedisTemplate<String, Address> redisTemplate2;
And, using following pattern to store data.
redisTemplate1.opsForHash().put("KEY1", student.getId(), student);
redisTemplate2.opsForHash().put("KEY1", address.getId(), address);
The case is, I have primary keys starting with 1 for each table. So 1 is there a primary key of Student as well as of Address.
I am using line below to get Student back from data-store.
(Student) redisTemplate1.opsForHash().get("KEY1", 1);
But, unfortunately it generates an exception.
java.lang.ClassCastException: com.redis.model.Address cannot be cast to com.redis.model.Student
So, my questions are,
Is it possible to use multiple redis templates ?
If yes, can I use same key (unique for each template) to store different types of data and access the same data stored using that template and key ?
If not, what are the alternative to perform same operation ?
Thanks in advance.
Actually Redis is a key/value store and if you use the same key for the same store you just override the old value with new one. And it doesn't matter how much RedisTemplates (or even connectionFactorys) you have, if the real Redis server is the same.
Now how to help you with your task:
You should have different kyes for different domain objects: e.g. students, addresses.
Since you are going to store domain objects with their own keys it looks like Map value is for you. I mean under key students a map of Students should be stored ,and the same for Addresses.
However you, actually, do it, but you use the same key for both domains.
So, the answer for you: that's because you are using the same Redis from both RedisTemplates.
When dealing with strings with Spring Data for Redis, I noticed the following behavior:
Given the code below:
template.opsForValue().set("person", "value");
it only works when I'm using an instance of StringRedisTemplate, and not when I'm using an instance of RedisTemplate. Should'nt it work with RedisTemplate since it aggregates all the operations for all the Redis data types?
StringRedisTemplate is just a specialization of RedisTemplate, so you should be able to use RedisTemplate directly if you prefer, provided that you set all the key/value serializers as is done in the constructor of StringRedisTemplate.
Perhaps you could provide more information about your configuration and what error you are getting? Also, why is StringRedisTemplate not a desirable option for your use case?