Skip to content

Add support for interface projection using Kotlin "is"-properties #3127

Closed
@sttomm

Description

@sttomm

When I upgraded our existing application from Spring Boot 3.1.12 to 3.2.8 I ran into the following error, which was not present before the upgrade:
.w.s.m.s.DefaultHandlerExceptionResolver : Resolved [org.springframework.http.converter.HttpMessageNotWritableException: Could not write JSON: Invalid property 'valid' of bean class [io.meshcloud.entitymodel_projection_issue.model.TestEntity]: Could not find field for property during fallback access]

I reproduced the issue with a minimal Spring Boot Application using Spring Data and Spring HATEOAS. The Controller is using a ProjectionFactory directly.

@GetMapping("/directProjections")
fun findDirectProjection(): ResponseEntity<*> {
    val entities = repo.findAll(PageRequest.of(0, 10))

    val projectedEntities = entities.map {
        projectionFactory.createProjection(EntityWithIsFieldProjection::class.java, it)
    }

    return ResponseEntity.ok(projectedEntities)
}

The entity looks like this (it has some "is"-properties):

@Entity
class TestEntity(
        @Id
        val id: Long,
        val mandatoryValue: String?,

        @get:JsonProperty("isGreat")
        val isGreat: Boolean
) {
    @get:JsonProperty("isValid")
    val isValid: Boolean
        get() = mandatoryValue != null
}

And the projection like this (also with the "is"-properties):

interface EntityWithIsFieldProjection {

    val projectedValue: String?
        @Value("#{target.mandatoryValue}")
        get() = projectedValue

    @get:JsonProperty("isGreat")
    val isGreat: Boolean

    @get:JsonProperty("isValid")
    val isValid: Boolean
}

When I call the controller endpoint, I get the error mentioned above. Sadly I could not get the Stacktrace for it, as the DefaultExceptionResolver just logged it as a warning.

Here is the small sample project I wrote to reproduce the issue:
failing-projection-json-mapping.zip

You can simply switch the spring boot version to 3.1.12 in there to see, that all tests in EntityModelTests succeed. But with 3.2.8 two of them fail.

I added some counter tests to see what happens if I don't use a projection or if I have a project that does not have a field starting with is and as expected, those cases work fine. So it seems to be something deep down in Spring Data Projections that leads to this issue.

I hope I provided sufficient details for you to reproduce the issue and provide a fix for it. I would be happy for a quick workaround if you could imagine any. I will also continue finding a workaround, as I don't want to rename all affected entities in our real application to not use "is"-properties.

Metadata

Metadata

Labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions