【发布时间】:2020-02-24 15:24:54
【问题描述】:
我们尝试在我们的项目中使用 Spring Data CrudRepository 来为我们的域对象提供持久性。
首先,我选择 REDIS 作为后端,因为在第一次使用 CrudRepository<ExperimentDomainObject, String> 的实验中,看起来运行起来很容易。
当尝试将它放入我们的生产代码时,事情变得更加复杂,因为在这里我们的域对象不需要使用简单类型作为键,所以存储库是 CrudRepository<TestObject, ObjectId>。
现在我得到了例外:
没有找到能够从 [...ObjectId] 类型转换为 [byte[]] 类型的转换器
搜索此异常,this answer,这导致我未经教育地尝试使用 RedisTemplate 配置。 (对于我的实验,我使用的是 emdedded-redis)
我的想法是,提供 RedisTemplate<Object, Object> 而不是 RedisTemplate<String, Object> 以允许使用 Jackson2JsonRedisSerializer 也可以作为 keySerializer 完成工作。
仍然,调用testRepository.save(testObject) 失败。
请看我的代码:
为了简洁起见,我有公共字段并省略了导入。如果需要它们(使其成为 MVCE),我将很乐意提供它们。给我留言吧。
依赖:
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-data-redis'
implementation 'org.springframework.boot:spring-boot-starter-web'
compileOnly 'org.projectlombok:lombok'
annotationProcessor 'org.projectlombok:lombok'
implementation group: 'redis.clients', name: "jedis", version: '2.9.0'
implementation group: 'it.ozimov', name: 'embedded-redis', version: '0.7.2'
}
Redis 配置:
@Configuration
@EnableRedisRepositories
public class RedisConfiguration {
@Bean
JedisConnectionFactory jedisConnectionFactory() {
return new JedisConnectionFactory();
}
@Bean
public RedisTemplate<Object, Object> redisTemplate() {
Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
final RedisTemplate<Object, Object> template = new RedisTemplate<>();
template.setConnectionFactory(jedisConnectionFactory());
template.setDefaultSerializer(jackson2JsonRedisSerializer);
template.setKeySerializer(jackson2JsonRedisSerializer);
template.setHashValueSerializer(jackson2JsonRedisSerializer);
template.setValueSerializer(jackson2JsonRedisSerializer);
template.setEnableDefaultSerializer(true);
return template;
}
}
测试对象
@RedisHash("test")
public class TestObject
{
@Id public ObjectId testId;
public String value;
public TestObject(ObjectId id, String value)
{
this.testId = id;
this.value = value; // In experiment this is: "magic"
}
}
对象标识
@EqualsAndHashCode
public class ObjectId {
public String creator; // In experiment, this is "me"
public String name; // In experiment, this is "fool"
}
测试库
@Repository
public interface TestRepository extends CrudRepository<TestObject, ObjectId>
{
}
EmbeddedRedisConfiguration
@Configuration
public class EmbeddedRedisConfiguration
{
private final redis.embedded.RedisServer redisServer;
EmbeddedRedisConfiguration(RedisProperties redisProperties)
{
this.redisServer = new redis.embedded.RedisServer(redisProperties.getPort());
}
@PostConstruct
public void init()
{
redisServer.start();
}
@PreDestroy
public void shutdown()
{
redisServer.stop();
}
}
应用:
@SpringBootApplication
public class ExperimentApplication
{
public static void main(String[] args)
{
SpringApplication.run(ExperimentApplication.class, args);
}
}
不是想要的答案:
当然,我可能会介绍一些特殊的 ID,它是一种简单的数据类型,例如我使用 jacksons ObjectMapper 手动构建的 JSON 字符串,然后使用 CrudRepository<TestObject, String>。
同时我也尝试过:
RedisTemplate<String, String>RedisTemplate<String, Object>- 自动装配
RedisTemplate并设置其默认序列化程序 - 注册
Converter<ObjectId, byte[]>到- 自动连线
ConverterRegistry - 自动连线的
GenericConversionService
但显然它们是错误的。
- 自动连线
【问题讨论】:
标签: java spring spring-data spring-data-redis spring-repositories