Spring-boot中将redis-cache反序列化为对象的问题

use*_*870 5 spring caching redis spring-boot

我在 Client 类中使用 JsonNode 来处理 MySQL 8 数据库中 JSON 类型的字段。即使对于 API 请求,它也能很好地工作。但是当我使用 Redis 启用缓存(我确实需要它)时,我注意到 Redis 无法序列化 JsonNode。我在网上搜索了更改Redis的序列化方法。并想出了以下代码:

\n\n
@Configuration\n@EnableCaching\npublic class RedisConfig {\n\n    @Bean\n    @Primary\n    public ObjectMapper objectMapper() {\n        return Jackson2ObjectMapperBuilder.json()\n                .serializationInclusion(JsonInclude.Include.NON_NULL) // Don\xe2\x80\x99t include null values\n                .featuresToDisable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS) //ISODate\n                .build();\n    }\n\n    @Bean\n    public RedisTemplate getRedisTemplate(ObjectMapper objectMapper, RedisConnectionFactory redisConnectionFactory){\n        RedisTemplate redisTemplate = new RedisTemplate<>();\n        redisTemplate.setDefaultSerializer(new GenericJackson2JsonRedisSerializer(objectMapper));\n        redisTemplate.setConnectionFactory(redisConnectionFactory);\n        return redisTemplate;\n    }\n\n    @Bean\n    @Primary\n    public RedisCacheConfiguration defaultCacheConfig(ObjectMapper objectMapper) {\n        return RedisCacheConfiguration.defaultCacheConfig()\n                .serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(new StringRedisSerializer()))\n                .serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(new GenericJackson2JsonRedisSerializer(objectMapper)));\n    }\n\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

它成功序列化我的对象并将它们成功放入 Redis,但无法反序列化它们!。并产生以下错误:

\n\n
\n

java.lang.ClassCastException:类 java.util.LinkedHashMap 无法转换为类 com.example.Client(java.util.LinkedHashMap 位于 loader \'bootstrap\' 的模块 \n java.base 中;com.example.客户端位于加载器的未命名\n模块\n org.springframework.boot.devtools.restart.classloader.RestartClassLoader\n @4683d900)]

\n
\n\n

这是我的客户类别:

\n\n
@Data\n@Entity\n@Table( name = "clients" )\n@EntityListeners(AuditingEntityListener.class)\n@TypeDef(name = "json", typeClass = JsonStringType.class)\npublic class Client  {\n    /**\n     * Id of the user\n     */\n    @Id\n    @GeneratedValue( strategy = GenerationType.IDENTITY )\n    private Long id;\n    /**\n     * UUID of the user.\n     */\n    @Column( name = "uuid", unique = true, updatable = false, nullable = false )\n    private String uuid;\n\n\n    /**\n     * Name of the client\n     */\n    @Column( name = "name", unique = true, nullable = false )\n    @Size( min=4, max=128, message = "client.exception.name.size" )\n    @NotBlank( message = "client.exception.name.isBlank" )\n    private String name;\n\n\n    /**\n     * Status of the client. Each client could have several statues.\n     * 1.\n     */\n    @Column( name = "client_status_id" )\n    @NotNull( message = "client.exception.status.isNull" )\n    @Enumerated( EnumType.ORDINAL )\n    private ClientStatus clientStatus = ClientStatus.Undefined;\n\n\n    /**\n     * Email address of the client.\n     */\n    @Column( name = "email" )\n    @NotBlank( message = "client.exception.email.isBlank")\n    @Size( min=5, max = 128, message = "client.exception.email.size")\n    @Email( message = "client.exception.email.notValid" )\n    private String email;\n\n    /**\n     * ClientNotFoundByIdException\'s phone number.\n     */\n    @Column( name = "phone" )\n    @NotBlank( message = "client.exception.phone.isBlank" )\n    @Size( min=3, max = 32, message = "client.exception.phone.size")\n    @Phone( message = "client.exception.phone.notValid" )\n    private String phone;\n\n    /**\n     * Whether client is active or not.\n     */\n    @Column( name = "is_active" )\n    private Boolean isActive = true;\n\n    /**\n     * Default timezone of the client.\n     */\n    @Column( name = "timezone" )\n    @NotBlank( message = "client.exception.timezone.isBlank" )\n    @Size( min = 4, max = 64, message = "client.exception.timezone.size" )\n    @TimeZone( message = "client.exception.timezone.notValid" )\n    private String timezone;\n\n\n    /**\n     * Country code of the client in ISO 3166-2\n     */\n    @Column( name = "country" )\n    @NotBlank( message = "client.exception.country.isBlank" )\n    @Size( min = 2, max = 4, message = "client.exception.country.size" )\n    @Country( message = "client.exception.country.notValid" )\n    private String country;\n\n\n    @Column( name = "language" )\n    @NotBlank( message = "client.exception.language.isBlank" )\n    @Size( min = 2, max = 3, message = "client.exception.language.size" )\n    @Language\n    private String language;\n\n\n    /**\n     * Extra fields for client in json\n     */\n    @Column( name = "fields", columnDefinition = "json" )\n    @Type( type = "json" )\n    @NotNull( message = "client.exception.fields.isNull" )\n    private JsonNode fields;\n\n\n    /**\n     * Creation time of the record.\n     */\n    @Column( name = "created_at", updatable = false )\n    @NotNull( message = "client.exception.createdAt.isNull")\n    @CreatedDate\n    private Instant createdAt;\n\n\n    /**\n     * The user that created the record.\n     */\n    @CreatedBy\n    @ManyToOne\n    @JoinColumn( name = "created_by" )\n    private User createdBy;\n\n\n    /**\n     * In which time the record is modified.\n     */\n    @Column( name = "updated_at" )\n    @NotNull( message = "client.exception.updatedAt.isNull" )\n    @LastModifiedDate\n    private Instant updatedAt;\n\n\n    /**\n     * By whom the record is modified.\n     */\n    @LastModifiedBy\n    @ManyToOne\n    @JoinColumn( name = "updated_by" )\n    private User updatedBy;\n\n\n    /**\n     * The time in which the record is deleted.\n     */\n    private Instant deletedAt;\n\n\n    /**\n     * By whom the record is deleted.\n     */\n    @ManyToOne\n    @JoinColumn( name = "deleted_by" )\n    private User deleteBy;\n\n\n    /**\n     * Version of the record.\n     */\n    @Version\n    private Long version;\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

更新:

\n\n

我注意到该错误与 JsonNode 无关,当我使用 GenericJackson2JsonRedisSerializer 时它会抛出异常。

\n

ste*_*stt 2

我遇到了非常相似的问题,解决方案很奇怪,但很简单 - 删除devtools依赖项。

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-devtools</artifactId>
    <optional>true</optional>
</dependency>
Run Code Online (Sandbox Code Playgroud)