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

KotlinBeanInfoFactory does not consider overridden bean property accessors #3140

Closed
MichaelKunze opened this issue Aug 20, 2024 · 4 comments
Closed
Assignees
Labels
type: enhancement A general enhancement

Comments

@MichaelKunze
Copy link

What is the issue?

With the introduction of Spring Boot 3.2, a behaviour by the KotlinBeanInfoFactory class is causing a problem of ignoring annotated getters in a Kotlin class and instead using getters from its (java) superclass.

How to reproduce?

You can reproduce this issue by creating a class in Kotlin and a superclass in Java. Annotate the getter in the Kotlin subclass with @id and observe that KotlinBeanInfoFactory does not recognize it.

Java Superclass:

public class Animal {
    private String name;

    // Getters and Setters
}

Kotlin Entityclass:

@Document
@TypeAlias("Dog")
open class DogEntity: Animal() {

    @Id
    override fun getName(): String {
        return super.getName()
    }
}

The intent is to enhance a generated java class with a certain field to be the id field of the collection.

Further analysis

KotlinBeanInfoFactory reads properties only from its Kotlin class and disregards any annotated getters. The resulting BeanInfo object includes a PropertyDescriptor for 'name', however, the getter for this property is acquired from the superclass, which does not carry any annotations. Thus, it seems like the 'id' field is not being properly initialized.

What did I expect?

The expected behavior is that KotlinBeanInfoFactory should recognize and prioritize annotated getters in a Kotlin subclass over those in its Java superclass, ensuring proper initialization of the 'id' field and other properties.

@spring-projects-issues spring-projects-issues added the status: waiting-for-triage An issue we've not yet triaged label Aug 20, 2024
@mp911de
Copy link
Member

mp911de commented Aug 20, 2024

As per Kotlin, your class doesn't define any properties hence KotlinBeanInfoFactory doesn't report any property. The properties that come from your superclass only consider methods defined in it (Animal).

Mixing properties regarding their origin isn't supported.

The purpose of KotlinBeanInfoFactory is to use Kotlin mechanism to detect properties.

@MichaelKunze
Copy link
Author

Well. My Java superclass is generated and i need to set one specific field as the id. My workaround is to turn the entity into a java class but that defeats the purpose of using kotlin.

@mp911de mp911de self-assigned this Sep 2, 2024
@mp911de mp911de changed the title Unexpected Behaviour of KotlinBeanInfoFactory in Spring Boot 3.2 KotlinBeanInfoFactory does not consider overridden bean property accessors Sep 2, 2024
@mp911de mp911de added type: enhancement A general enhancement and removed status: waiting-for-triage An issue we've not yet triaged labels Sep 2, 2024
@mp911de mp911de added this to the 3.3.4 (2024.0.4) milestone Sep 2, 2024
@mp911de
Copy link
Member

mp911de commented Sep 2, 2024

We can introduce accessor specialization to detect getters and specialize accessor methods if the type hierarchy declares overrides. The only constraint however is that property names must be unique.

mp911de added a commit that referenced this issue Sep 2, 2024
We now attempt to detect property accessors for properties declared in Kotlin that do not have a Kotlin-style accessor but one that instead comes from an interface.

Also, we specialize accessor methods that are inherited from a Java superclass but override accessors in the Kotlin realm.

Closes #3140
Closes #3146
@mp911de mp911de closed this as completed in b99db0c Sep 2, 2024
mipo256 pushed a commit to mipo256/spring-data-commons that referenced this issue Sep 21, 2024
We now attempt to detect property accessors for properties declared in Kotlin that do not have a Kotlin-style accessor but one that instead comes from an interface.

Also, we specialize accessor methods that are inherited from a Java superclass but override accessors in the Kotlin realm.

Closes spring-projects#3140
Closes spring-projects#3146
@mapuo
Copy link

mapuo commented Sep 24, 2024

I have the same issue, but I'm not using Kotlin - just plain Java 21. After upgrading to 3.3.3 I get Caused by: java.lang.IllegalStateException: Invoked method is not a property accessor and I'm not sure what exactly is the issue.
In my case I have a Date getCreatedAt(); in the projection interface and the entity is inheriting this property/getter from a base class. Is the issue that the property is not defined in the entity class?

Edit: I've override the methods from the base class and it works again - it seems that the projection have lost the ability to look into the super class(es) for the method.

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

No branches or pull requests

4 participants