spring boot @Cachable 返回用空值填充的超类的所有字段

xst*_*ing 3 spring spring-mvc hazelcast spring-boot

我们面临着一个奇怪的问题,我不明白发生了什么,并希望其他人已经遇到了同样的问题并知道发生了什么。

我们使用 @Cachable 编写了一个简单的 REST 服务:

@GetMapping(value = "/get/{" + PARAM_TENANT + "}/{" + PARAM_UID + "}")
@Cacheable(value = GET_ORDERS_BY_UID )
public GetOrdersResponseDto getOrdersByUid(@PathVariable final String tenant, @PathVariable final String uid) {
        ....
        return new GetOrdersResponseDto(createCacheKey(), orderResponseDtos);
}
Run Code Online (Sandbox Code Playgroud)

GetOrdersResponseDto 由多个字段组成。有些包含自定义类的实例,有些包含自定义类的列表以及其他简单的原始值。

当从缓存提供 GetOrdersResponseDto 响应时,存储在列表内并且位于对象超类中的所有对象字段都将填充空值。

我们使用 hazelcast 作为缓存实现。我们的缓存配置非常基本:

@Component
public class HazelcastConfig extends Config {

@Autowired
public HazelcastConfig(final ConfigClient configClient) {
    super();

    final GroupConfig groupConfig = getGroupConfig();
    final String name = configClient
        .getConfigPropertyValueOrThrow("public", "com.orderservice.hazelcast.group.name");
    groupConfig.setName("foogroup");

    final String password = configClient
        .getConfigPropertyValueOrThrow("public", "com.orderservice.hazelcast.group.password");
    groupConfig.setPassword(password);
Run Code Online (Sandbox Code Playgroud)

响应类如下所示:

public class GetOrdersResponseDto implements Serializable {

    private String cacheSerial;

    private List<OrderResponseDto> orderResponseDtos;

}
Run Code Online (Sandbox Code Playgroud)

并且该问题仅发生在属于 OrderResponseDto 超类的 OrderResponseDto 字段中。

我希望有人能给我们提示这种奇怪行为的原因是什么。

编辑:我发现,问题只发生在存储在列表中的对象......

小智 5

这是 Java 的行为。请参阅https://docs.oracle.com/javase/8/docs/api/java/io/Serializing.html

如果您的对象是可序列化的并扩展了一个不可序列化的对象,那么NotSerializeException父对象的字段只会被初始化,而不是有用的,这就是为什么您将它们设置为空。

您可以在单元测试中证明这一点。这是一个可以重用的 - https://github.com/hazelcast/hazelcast-code-samples/blob/master/serialization/hazelcast-airlines/the-code/src/test/java/com/hazelcast/samples/serialization/hazelcast /airlines/V1FlightTest.java