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

2024-06-19

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

@Configuration
@EnableCaching
public class RedisConfig {

    @Bean
    @Primary
    public ObjectMapper objectMapper() {
        return Jackson2ObjectMapperBuilder.json()
                .serializationInclusion(JsonInclude.Include.NON_NULL) // Don’t include null values
                .featuresToDisable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS) //ISODate
                .build();
    }

    @Bean
    public RedisTemplate getRedisTemplate(ObjectMapper objectMapper, RedisConnectionFactory redisConnectionFactory){
        RedisTemplate redisTemplate = new RedisTemplate<>();
        redisTemplate.setDefaultSerializer(new GenericJackson2JsonRedisSerializer(objectMapper));
        redisTemplate.setConnectionFactory(redisConnectionFactory);
        return redisTemplate;
    }

    @Bean
    @Primary
    public RedisCacheConfiguration defaultCacheConfig(ObjectMapper objectMapper) {
        return RedisCacheConfiguration.defaultCacheConfig()
                .serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(new StringRedisSerializer()))
                .serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(new GenericJackson2JsonRedisSerializer(objectMapper)));
    }

}

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

java.lang.ClassCastException:类 java.util.LinkedHashMap 不能 转换为 com.example.Client 类(java.util.LinkedHashMap 位于模块中 加载器'bootstrap'的java.base; com.example.Client 处于未命名状态 装载机模块 org.springframework.boot.devtools.restart.classloader.RestartClassLoader @4683d900)]

这是我的客户类别:

@Data
@Entity
@Table( name = "clients" )
@EntityListeners(AuditingEntityListener.class)
@TypeDef(name = "json", typeClass = JsonStringType.class)
public class Client  {
    /**
     * Id of the user
     */
    @Id
    @GeneratedValue( strategy = GenerationType.IDENTITY )
    private Long id;
    /**
     * UUID of the user.
     */
    @Column( name = "uuid", unique = true, updatable = false, nullable = false )
    private String uuid;


    /**
     * Name of the client
     */
    @Column( name = "name", unique = true, nullable = false )
    @Size( min=4, max=128, message = "client.exception.name.size" )
    @NotBlank( message = "client.exception.name.isBlank" )
    private String name;


    /**
     * Status of the client. Each client could have several statues.
     * 1.
     */
    @Column( name = "client_status_id" )
    @NotNull( message = "client.exception.status.isNull" )
    @Enumerated( EnumType.ORDINAL )
    private ClientStatus clientStatus = ClientStatus.Undefined;


    /**
     * Email address of the client.
     */
    @Column( name = "email" )
    @NotBlank( message = "client.exception.email.isBlank")
    @Size( min=5, max = 128, message = "client.exception.email.size")
    @Email( message = "client.exception.email.notValid" )
    private String email;

    /**
     * ClientNotFoundByIdException's phone number.
     */
    @Column( name = "phone" )
    @NotBlank( message = "client.exception.phone.isBlank" )
    @Size( min=3, max = 32, message = "client.exception.phone.size")
    @Phone( message = "client.exception.phone.notValid" )
    private String phone;

    /**
     * Whether client is active or not.
     */
    @Column( name = "is_active" )
    private Boolean isActive = true;

    /**
     * Default timezone of the client.
     */
    @Column( name = "timezone" )
    @NotBlank( message = "client.exception.timezone.isBlank" )
    @Size( min = 4, max = 64, message = "client.exception.timezone.size" )
    @TimeZone( message = "client.exception.timezone.notValid" )
    private String timezone;


    /**
     * Country code of the client in ISO 3166-2
     */
    @Column( name = "country" )
    @NotBlank( message = "client.exception.country.isBlank" )
    @Size( min = 2, max = 4, message = "client.exception.country.size" )
    @Country( message = "client.exception.country.notValid" )
    private String country;


    @Column( name = "language" )
    @NotBlank( message = "client.exception.language.isBlank" )
    @Size( min = 2, max = 3, message = "client.exception.language.size" )
    @Language
    private String language;


    /**
     * Extra fields for client in json
     */
    @Column( name = "fields", columnDefinition = "json" )
    @Type( type = "json" )
    @NotNull( message = "client.exception.fields.isNull" )
    private JsonNode fields;


    /**
     * Creation time of the record.
     */
    @Column( name = "created_at", updatable = false )
    @NotNull( message = "client.exception.createdAt.isNull")
    @CreatedDate
    private Instant createdAt;


    /**
     * The user that created the record.
     */
    @CreatedBy
    @ManyToOne
    @JoinColumn( name = "created_by" )
    private User createdBy;


    /**
     * In which time the record is modified.
     */
    @Column( name = "updated_at" )
    @NotNull( message = "client.exception.updatedAt.isNull" )
    @LastModifiedDate
    private Instant updatedAt;


    /**
     * By whom the record is modified.
     */
    @LastModifiedBy
    @ManyToOne
    @JoinColumn( name = "updated_by" )
    private User updatedBy;


    /**
     * The time in which the record is deleted.
     */
    private Instant deletedAt;


    /**
     * By whom the record is deleted.
     */
    @ManyToOne
    @JoinColumn( name = "deleted_by" )
    private User deleteBy;


    /**
     * Version of the record.
     */
    @Version
    private Long version;
}

Update:

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


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

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-devtools</artifactId>
    <optional>true</optional>
</dependency>
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

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

随机推荐