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

Different creator parameter null behavior for 2.17.3 and 2.18.2 #874

Open
2 of 4 tasks
hykilpikonna opened this issue Dec 30, 2024 · 4 comments
Open
2 of 4 tasks
Labels

Comments

@hykilpikonna
Copy link

hykilpikonna commented Dec 30, 2024

Search before asking

  • I searched in the issues and found nothing similar.
  • I have confirmed that the same problem is not reproduced if I exclude the KotlinModule.
  • I searched in the issues of databind and other modules used and found nothing similar.
  • I have confirmed that the problem does not reproduce in Java and only occurs when using Kotlin and KotlinModule.

Describe the bug

After upgrading from jackson 2.17.3 to 2.18.1, the following error occurs when trying to deserialize null into an inherited field with a default value that also has a required constructor.

Exception in thread "main" com.fasterxml.jackson.module.kotlin.MissingKotlinParameterException: Instantiation of [simple type, class icu.samnyan.aqua.sega.chusan.model.userdata.UserActivity] value failed for JSON property user due to missing (therefore NULL) value for creator parameter user which is a non-nullable type
 at [Source: REDACTED (`StreamReadFeature.INCLUDE_SOURCE_IN_LOCATION` disabled); line: 1, column: 76] (through reference chain: icu.samnyan.aqua.sega.chusan.model.userdata.UserActivity["user"])
	at com.fasterxml.jackson.module.kotlin.KotlinValueInstantiator.createFromObjectWith(KotlinValueInstantiator.kt:97)
	at com.fasterxml.jackson.databind.deser.impl.PropertyBasedCreator.build(PropertyBasedCreator.java:214)
	at com.fasterxml.jackson.databind.deser.BeanDeserializer._deserializeUsingPropertyBased(BeanDeserializer.java:541)
	at com.fasterxml.jackson.databind.deser.BeanDeserializerBase.deserializeFromObjectUsingNonDefault(BeanDeserializerBase.java:1497)
	at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserializeFromObject(BeanDeserializer.java:348)
	at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:185)
	at com.fasterxml.jackson.databind.deser.DefaultDeserializationContext.readRootValue(DefaultDeserializationContext.java:342)
	at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:4917)
	at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:3860)
	at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:3843)
	at test.JsonTestKt.main(JsonTest.kt:25)

To Reproduce

Here are my model definitions. Note that the user field in the parent has a default value, but the UserActivity class also has a constructor parameter user that doesn't have a default value.

@MappedSuperclass
open class BaseEntity(
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @JsonIgnore
    open var id: Long = 0
)

@MappedSuperclass
open class Chu3UserEntity : BaseEntity(), IUserEntity<Chu3UserData> {
    @JsonIgnore
    @ManyToOne
    @JoinColumn(name = "user_id")
    public override var user: Chu3UserData = Chu3UserData()
}

@Entity(name = "ChusanUserActivity")
@Table(name = "chusan_user_activity")
class UserActivity(user: Chu3UserData) : Chu3UserEntity() {
    init { this.user = user }

    var kind = 0
    @JsonProperty("id")
    @Column(name = "activity_id")
    var activityId = 0
    var sortNumber = 0
}

The following code will run successfully on Jackson (+kotlin module) 2.15 but fail on 2.18:

fun main(args: Array<String>) {
    val mapper = jacksonObjectMapper().apply {
        configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
        configure(SerializationFeature.WRITE_ENUMS_USING_INDEX, true)
        findAndRegisterModules()
    }
    val json = mapper.writeValueAsString(UserActivity(Chu3UserData()))
    mapper.readValue<UserActivity>(json)
}

Expected behavior

I do not expect null-handling behavior to subtly change when upgrading between minor versions of jackson-module-kotlin.

Versions

Kotlin: 2.1.0
Jackson-module-kotlin: 2.18.2
Jackson-databind: 2.18.2

Additional context

No response

@hykilpikonna hykilpikonna changed the title Different creator parameter null behavior for 2.15.4 and 2.18.2 Different creator parameter null behavior for 2.17.3 and 2.18.1 Dec 30, 2024
@hykilpikonna
Copy link
Author

Just tested that 2.17.3 does not have this issue.

@k163377
Copy link
Contributor

k163377 commented Dec 30, 2024

@hykilpikonna
Would it be possible for you to test the same in 2.18.2?

@hykilpikonna
Copy link
Author

Would it be possible for you to test the same in 2.18.2?

2.18.2 has the same issue as 2.18.1

@k163377 k163377 changed the title Different creator parameter null behavior for 2.17.3 and 2.18.1 Different creator parameter null behavior for 2.17.3 and 2.18.2 Jan 2, 2025
@k163377
Copy link
Contributor

k163377 commented Jan 2, 2025

@hykilpikonna
The code you attached seems incomplete.
At least the definition of Chu3UserData is missing.

Also, if you resubmit the code, I would appreciate the following

  1. Remove as much of the code other than Jackson as possible, such as annotations
  2. Remove as much code as possible that registers anything other than kotlin-module, to the extent that the problem can be reproduced.
  3. Attach the import correctly as well.

In 2.18, databind has been modified to handle single argument constructors.
If that is the cause, adding @JsonCreator(mode = Mode.DELEGATING) to the constructor may improve it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants