Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Backport GenericJackson2JsonRedisSerializer.configure(…) to 3.1.x #2722

Closed
roeniss opened this issue Sep 30, 2023 · 6 comments
Closed

Backport GenericJackson2JsonRedisSerializer.configure(…) to 3.1.x #2722

roeniss opened this issue Sep 30, 2023 · 6 comments
Assignees
Labels
status: invalid An issue that we don't feel is valid

Comments

@roeniss
Copy link

roeniss commented Sep 30, 2023

GenericJackson2JsonRedisSerializer(ObjectMapper mapper) constructor removes the chance to apply setup in GenericJackson2JsonRedisSerializer(@Nullable String classPropertyTypeName).

Currently I managed to make copy of GenericJackson2JsonRedisSerializer.TypeResolverBuilder like this:

    @Bean
    GenericJackson2JsonRedisSerializer genericJackson2JsonRedisSerializer(ObjectMapper mapper) {
        GenericJackson2JsonRedisSerializer serializer = new GenericJackson2JsonRedisSerializer(mapper);
        GenericJackson2JsonRedisSerializer.registerNullValueSerializer(mapper, null);

        StdTypeResolverBuilder typer = new TypeResolverBuilder(DefaultTyping.EVERYTHING,
                mapper.getPolymorphicTypeValidator());
        typer = typer.init(JsonTypeInfo.Id.CLASS, null);
        typer = typer.inclusion(JsonTypeInfo.As.PROPERTY);
        
        if (StringUtils.hasText(classPropertyTypeName)) {
	        typer = typer.typeProperty(classPropertyTypeName);
        }
        mapper.setDefaultTyping(typer);

        return serializer;
    }

    private static class TypeResolverBuilder extends ObjectMapper.DefaultTypeResolverBuilder {
        // ... (same implementation with original)
    }

original in the comment means this: https://github.com/spring-projects/spring-data-redis/blob/main/src/main/java/org/springframework/data/redis/serializer/GenericJackson2JsonRedisSerializer.java#L381

I hope there's a more simple way to do this.

@spring-projects-issues spring-projects-issues added the status: waiting-for-triage An issue we've not yet triaged label Sep 30, 2023
@jxblum
Copy link
Contributor

jxblum commented Oct 2, 2023

From your code snippet above, it is not apparent what aspects of Jackson's ObjectMapper you customized. I assume you declared an object of type ObjectMapper as a managed bean in the Spring context? The question is, does the ObjectMapper instance really need to be managed by the Spring container?

NOTE: There are other situations where Spring Data Redis's GenericJackson2JsonRedisSerializer creates and maintains separate and internal instances of ObjectMapper. For example.

It is apparent that you are duplicating the logic from this constructor, but are allowing the ObjectMapper to passed during construction, presumably because you constructed a "custom" instance of ObjectMapper as a managed bean in the Spring container.

You can accomplish this another way, if you do not need the ObjectMapper to strictly be a managed bean in the Spring context.

NOTE: For the record, is it questionable whether declaring an ObjectMapper as a managed bean is strictly necessary given customizations are quite use case and/or domain specific.

Simply do the following:

@Configuration
class MyApplicationRedisConfiguration {

    @Bean
    GenericJackson2JsonRedisSerializer jsonRedisSerializer(
            @Value("${spring.redis.serialization.class-property-type-name}") String classPropertyTypeName) {

        GenericJackson2JsonRedisSerializer jsonRedisSerializer = 
            new GenericJackson2JsonRedisSerializer(classPropertyTypeName);

        jsonRedisSerializer.configure(objectMapper -> {
            // add ObjectMapper customizations here
        });

        return jsonRedisSerializer;
    }
}

Additionally, your "jsonRedisSerializer" @Bean method could also be "injected" with other configuration used to customize the ObjectMapper created by Spring Data Redis's GenericJackson2JsonRedisSerializer (as seen here).

I demonstrated such an injection with the classPropertyTypeName configuration. Clearly, you are able to add others.

@jxblum jxblum added in: core Issues in core support status: waiting-for-feedback We need additional information before we can continue status: invalid An issue that we don't feel is valid and removed status: waiting-for-triage An issue we've not yet triaged labels Oct 2, 2023
@jxblum jxblum changed the title GenericJackson2JsonRedisSerializer Constructor for custom ObjectMapper with default setup GenericJackson2JsonRedisSerializer constructor for custom ObjectMapper with default setup Oct 2, 2023
@jxblum jxblum changed the title GenericJackson2JsonRedisSerializer constructor for custom ObjectMapper with default setup GenericJackson2JsonRedisSerializer constructor for custom ObjectMapper with default setup Oct 2, 2023
@roeniss
Copy link
Author

roeniss commented Oct 2, 2023

configure is the one that I need. Thank you jxblum! I'm using Spring bom 2.7.15 so I didn't notice such method exists (that method is added on 3.1.1 with this PR).

The question is, does the ObjectMapper instance really need to be managed by the Spring container?

I needed not the one in Spring container but one with jsr310 module added. When I debugged, objectmapper that is newly made in GenericJackson2JsonRedisSerializer has only one module, and Spring-managed objectmapper has 7 modules including jsr310 (for me, it is needed to serialize/deserialize Instant type). I had to use Spring's one or make one by myself. Either way needs duplicating logic as you might guess.

@spring-projects-issues spring-projects-issues added status: feedback-provided Feedback has been provided and removed status: waiting-for-feedback We need additional information before we can continue labels Oct 2, 2023
@jxblum
Copy link
Contributor

jxblum commented Oct 2, 2023

Hi @roeniss - Right, I was also wondering the version of the Spring (Boot/Data) BOM you had in play. Thank you for sharing that information. I always base my answers on the latest bits if not otherwise specified.

Anyway, I will talk to the team about potentially back porting this method (configure(:Consumer<ObjectMapper>)).

@jxblum jxblum added status: on-hold We cannot start working on this issue yet for: team-attention An issue we need to discuss as a team to make progress and removed status: feedback-provided Feedback has been provided labels Oct 2, 2023
@roeniss
Copy link
Author

roeniss commented Oct 2, 2023

Thank you so much! Farewell.

@jxblum jxblum removed the status: invalid An issue that we don't feel is valid label Oct 2, 2023
@jxblum
Copy link
Contributor

jxblum commented Oct 3, 2023

@mp911de & @christophstrobl - I propose we (minimally) back port the configure(:Consumer<ObjectMapper>) method (source & Javadoc) I added to SD Redis to resolve Issue #2601, to 3.0.x and 2.7.x.

Thoughts?

@mp911de mp911de self-assigned this Oct 13, 2023
@mp911de mp911de added type: enhancement A general enhancement and removed status: on-hold We cannot start working on this issue yet for: team-attention An issue we need to discuss as a team to make progress labels Oct 13, 2023
@mp911de mp911de changed the title GenericJackson2JsonRedisSerializer constructor for custom ObjectMapper with default setup Backport GenericJackson2JsonRedisSerializer.configure(…) to 3.1.x Oct 13, 2023
@mp911de mp911de added this to the 3.1.5 (2023.0.5) milestone Oct 13, 2023
@mp911de
Copy link
Member

mp911de commented Oct 13, 2023

As this change (GenericJackson2JsonRedisSerializer.configure(…)) is already part of 3.1.x, closing this issue.

@mp911de mp911de closed this as not planned Won't fix, can't repro, duplicate, stale Oct 13, 2023
@mp911de mp911de added status: invalid An issue that we don't feel is valid and removed in: core Issues in core support type: enhancement A general enhancement labels Oct 13, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
status: invalid An issue that we don't feel is valid
Projects
None yet
Development

No branches or pull requests

4 participants