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

Filter annotated by JsonInclude.Include.CUSTOM does not get called if the field is null with afterburner module registered #3689

Closed
aerisnju opened this issue Dec 5, 2022 · 2 comments
Labels
duplicate Duplicate of an existing (usually earlier) issue
Milestone

Comments

@aerisnju
Copy link

aerisnju commented Dec 5, 2022

Describe the bug
Related with issue #3481 and PR #3486 . If we enable afterburner module, the serializer will skip custom include filter for fields with null values and always include them in the serialized json string.

Version information
jackson version >= 2.14

To Reproduce
Let me use Kotlin as the programming language, but I think it's nothing to do with the Kotlin module.
Suppose we have the filter:

class CustomFilter {
     override fun equals(other: Any?): Boolean {
         println("Filter called")   // Print something to show that the filter gets called
         return true  // Always filter out
     }
 }

and the simple data class

data class User(
     val name: String,
     @JsonInclude(JsonInclude.Include.CUSTOM, valueFilter = CustomFilter::class)
     val phoneNo: String?
 )

Let's create an ObjectMapper

val mapper = ObjectMapper().registerKotlinModule().registerModule(AfterburnerModule()) // Kotlin and Afterburner modules are registered

Serialize the data:

val user = User("Alice", null)  // phoneNo is null
val jsonString = mapper.writeValueAsString(user)
println(jsonString)

We got the result:

{"name":"Alice","phoneNo":null}

We can see that a) the filter is not called (or it will print "Filter called") and b) the field with null value is serialized but we expect it not get serialized.

Expected behavior
If we change the mapper creation and do not register the afterburner module like this:

val mapper = ObjectMapper().registerKotlinModule() // Only Kotlin module is registered

Just change the single line above and we will get the expected result:

Filter called
{"name":"Alice"}

Additional context
The root cause is the incomplete change in PR #3486. We changed the behavior of BeanPropertyWriter, but there are several subclasses of BeanPropertyWriter in the afterburner module (most noticeable one is ObjectFieldPropertyWriter). And the code resides in these classes is not changed in the PR, which causes inconsistent behavior. I suggest reviewing and modifying the related code in the afterburner module to keep the consistent behavior, or rollback the previous change #3486 (and subsequent changes if possible) to revert to the original but consistent behavior.

@aerisnju aerisnju added the to-evaluate Issue that has been received but not yet evaluated label Dec 5, 2022
@aerisnju aerisnju changed the title Filter annotated by JsonInclude.Include.CUSTOM does not got called if the field is null with afterburner module registered Filter annotated by JsonInclude.Include.CUSTOM does not get called if the field is null with afterburner module registered Dec 5, 2022
@cowtowncoder
Copy link
Member

Ok. Afterburner is challenging for this reason (ditto for Blackbird). I don't have a good solution to offer as part of the challenge is test coverage; how to automate things to test both with and without AB/BB all regular databind tests, but ideally with minimal duplication of test code.

I need to move the issue to Afterburner repo as it needs to be fixed there.

Or rather, I think I'll just create a separate one there, link to this one.

I probably won't have time to work on this myself but this is something for which making PR might be simple enough to do -- add test(s) first on Afterburner/Blackbird side, then modify handling.

@cowtowncoder
Copy link
Member

Fixed in jackson-modules-base.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
duplicate Duplicate of an existing (usually earlier) issue
Projects
None yet
Development

No branches or pull requests

2 participants