Skip to content

Java Records missing type information with DefaultTyping.NON_FINAL (add DefaultTyping.NON_FINAL_AND_RECORDS) #5223

Description

@cndqjacndqja

Search before asking

  • I searched in the issues and found nothing similar.

Describe the bug

Java Records fail to include @Class type information when using DefaultTyping.NON_FINAL, causing Redis caching deserialization failures in Spring Boot applications.

Version Information

2.17.3

Reproduction

@Configuration
public class RedisConfig {
    @Bean
    public RedisCacheManager cacheManager(RedisConnectionFactory connectionFactory) {
        RedisCacheConfiguration cacheConfiguration = RedisCacheConfiguration.defaultCacheConfig()
                .serializeValuesWith(RedisSerializationContext.SerializationPair
                    .fromSerializer(new GenericJackson2JsonRedisSerializer(createRedisObjectMapper())));
        return RedisCacheManager.builder(connectionFactory)
                .cacheDefaults(cacheConfiguration)
                .build();
    }
    
    private static ObjectMapper createRedisObjectMapper() {
        final ObjectMapper mapper = new ObjectMapper();
        mapper.activateDefaultTyping(
            mapper.getPolymorphicTypeValidator(),
            DefaultTyping.NON_FINAL,  // Records are excluded here
            JsonTypeInfo.As.PROPERTY
        );
        return mapper;
    }
}
public record UserRecord(Long id, String name) {}
@Service
public class UserService {
    @Cacheable("users")
    public UserRecord getUser(Long id) {
        return new UserRecord(id, "User-" + id);
    }
}
@Test
void testRecordCaching() {
    UserRecord user1 = userService.getUser(1L); // ✅ Works
    UserRecord user2 = userService.getUser(1L); // ❌ Fails
}

exception message: com.fasterxml.jackson.databind.exc.InvalidTypeIdException:
Could not resolve subtype of [simple type, class java.lang.Object]:
missing type id property '@Class'

Expected behavior

No response

Additional context

Related to Previous Issue #3512:

This issue was previously reported in #3512 and closed with the following recommendations:

  • Use DefaultTyping.EVERYTHING instead of NON_FINAL for Records
  • Consider using regular classes instead of Records

However, these solutions have limitations:

DefaultTyping.EVERYTHING concerns:

  • Planned for deprecation and removal in Jackson 3.0 (#4160)
  • Includes unnecessary type metadata for all fields, raising security concerns
  • No clear migration path for Jackson 3.0

"Avoid Records" approach issues:

  • High risk of human error (developers forgetting which pattern to use)

Thank you for your consideration.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

3.1RecordIssue related to JDK17 java.lang.Record supportpr-welcomeIssue for which progress most likely if someone submits a Pull Request

Type

No type

Projects

No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions