英文:
Deserialize class with @AutoValue annotation during getting from cache in SpringBoot application
问题
我使用了com.google.auto.value.AutoValue
注解创建了一个值类:
@AutoValue
@JsonDeserialize(builder = AutoValue_Company.Builder.class)
public abstract class Company {
public static Builder newBuilder() {
return new AutoValue_Company.Builder();
}
@JsonProperty("id")
public abstract long id();
@JsonProperty("description")
public abstract String description();
@JsonProperty("websiteUrl")
public abstract String websiteUrl();
@AutoValue.Builder
public interface Builder {
@JsonProperty("id")
Builder id(long id);
@JsonProperty("description")
Builder description(String description);
@JsonProperty("websiteUrl")
Builder websiteUrl(String url);
Company build();
}
}
这样的类的实例是从服务中接收的,并且结果被缓存在Redis中:
@Cacheable(value = "company")
public Company getValue(String id)
以下是RedisCacheManager的配置:
@Bean(name = "valueCacheManager")
public RedisCacheManager valueCacheManager(final RedisConnectionFactory connectionFactory) {
final RedisCacheWriter redisCacheWriter = RedisCacheWriter.lockingRedisCacheWriter(connectionFactory);
RedisCacheConfiguration cacheConfiguration = RedisCacheConfiguration.defaultCacheConfig()
.serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(new GenericJackson2JsonRedisSerializer()));
cacheConfiguration = cacheConfiguration.entryTtl(Duration.ofSeconds(100));
return new RedisCacheManager(redisCacheWriter, cacheConfiguration);
}
结果是与反序列化相关的问题:
com.fasterxml.jackson.databind.exc.InvalidDefinitionException: No serializer found for class com.test.models.AutoValue_Company and no properties discovered to create BeanSerializer (to avoid exception, disable SerializationFeature.FAIL_ON_EMPTY_BEANS)
英文:
I've created a value class with com.google.auto.value.AutoValue
annotation:
@AutoValue
@JsonDeserialize(builder = AutoValue_Company.Builder.class)
public abstract class Company {
public static Builder newBuilder() {
return new AutoValue_Company.Builder();
}
@JsonProperty("id")
public abstract long id();
@JsonProperty("description")
public abstract String description();
@JsonProperty("websiteUrl")
public abstract String websiteUrl();
@AutoValue.Builder
public interface Builder {
@JsonProperty("id")
Builder id(long id);
@JsonProperty("description")
Builder description(String description);
@JsonProperty("websiteUrl")
Builder websiteUrl(String url);
Company build();
}
}
Instance of such class is received from service and result is cached in Redis:
@Cacheable(value = "company")
public Company getValue(String id)
Here is the config of RedisCacheManager:
@Bean(name = "valueCacheManager")
public RedisCacheManager valueCacheManager(final RedisConnectionFactory connectionFactory) {
final RedisCacheWriter redisCacheWriter = RedisCacheWriter.lockingRedisCacheWriter(connectionFactory);
RedisCacheConfiguration cacheConfiguration = RedisCacheConfiguration.defaultCacheConfig()
.serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(new GenericJackson2JsonRedisSerializer()));
cacheConfiguration = cacheConfiguration.entryTtl(Duration.ofSeconds(100));
return new RedisCacheManager(redisCacheWriter, cacheConfiguration);
}
As a result the issue that is connected to deserialization:
com.fasterxml.jackson.databind.exc.InvalidDefinitionException: No serializer found for class com.test.models.AutoValue_Company and no properties discovered to create BeanSerializer (to avoid exception, disable SerializationFeature.FAIL_ON_EMPTY_BEANS)
答案1
得分: 2
The solution was found by changing serializer GenericJackson2JsonRedisSerializer
to Jackson2JsonRedisSerializer<>(Company.class)
.
So the cache config now looks like that:
@Bean(name = "valueCacheManager")
public RedisCacheManager valueCacheManager(final RedisConnectionFactory connectionFactory) {
final RedisCacheWriter redisCacheWriter = RedisCacheWriter.lockingRedisCacheWriter(connectionFactory);
RedisCacheConfiguration cacheConfiguration = RedisCacheConfiguration.defaultCacheConfig()
.serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(new Jackson2JsonRedisSerializer<>(Company.class)));
cacheConfiguration = cacheConfiguration.entryTtl(Duration.ofSeconds(100));
return new RedisCacheManager(redisCacheWriter, cacheConfiguration);
}
英文:
The solution was found by changing serializer GenericJackson2JsonRedisSerializer
to Jackson2JsonRedisSerializer<>(Company.class)
So the cache config now looks like that:
@Bean(name = "valueCacheManager")
public RedisCacheManager valueCacheManager(final RedisConnectionFactory connectionFactory) {
final RedisCacheWriter redisCacheWriter = RedisCacheWriter.lockingRedisCacheWriter(connectionFactory);
RedisCacheConfiguration cacheConfiguration = RedisCacheConfiguration.defaultCacheConfig()
.serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(new Jackson2JsonRedisSerializer<>(Company.class)));
cacheConfiguration = cacheConfiguration.entryTtl(Duration.ofSeconds(100));
return new RedisCacheManager(redisCacheWriter, cacheConfiguration);
}
答案2
得分: 0
或许你应该使用getter的命名约定来命名你的方法,例如getId()
等?我认为这个链接与此相关。
英文:
Maybe you should name your methods using getters convention e.g. getId()
etc? I think this is related.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论