Skip to content

Kotlin lazy property identified as persistent entity #3112

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

Closed
maio opened this issue Jun 21, 2024 · 4 comments
Closed

Kotlin lazy property identified as persistent entity #3112

maio opened this issue Jun 21, 2024 · 4 comments
Assignees
Labels
type: enhancement A general enhancement

Comments

@maio
Copy link

maio commented Jun 21, 2024

Hello,

first thanks for a great library!

I encountered following problem. I have a Money data class in Kotlin and when I try to use it in my
DB entity as an @Embedded as follows:

data class Money(val value: BigDecimal, val currency: String) {
    val foo by lazy { 123 }
}

interface CardsRepositoryV1 : CrudRepository<CardsRepositoryV1.CardRow, Long> {
    @Table(value = "cards_v1")
    data class CardRow(
        ...,
        @Embedded(prefix = "effective_amount_", onEmpty = Embedded.OnEmpty.USE_NULL)
        val effectiveAmount: Money
    )
}

repository.deleteAll()

Then I get this error:

org.springframework.data.relational.core.conversion.DbActionExecutionException: Failed to execute DbAction.DeleteAll(propertyPath=effectiveAmount.foo$delegate)
Caused by: org.h2.jdbc.JdbcSQLSyntaxErrorException: Table "LAZY" not found; SQL statement:
DELETE FROM "LAZY" WHERE "LAZY"."CARDS_V1" IS NOT NULL [42102-224]

Am I doing something wrong?

PS: I'm using Spring Boot 3.2.5

Thanks,
Marian

@spring-projects-issues spring-projects-issues added the status: waiting-for-triage An issue we've not yet triaged label Jun 21, 2024
@schauder
Copy link
Contributor

Please provide a Minimimal Reproducable Example, preferable as a Github repository. Make sure to include the database, either as an in memory database or if that is not possible using Testcontainers.

@schauder schauder added the status: waiting-for-feedback We need additional information before we can continue label Jun 21, 2024
@maio
Copy link
Author

maio commented Jun 21, 2024

Thanks for quick reply. Here is the repository: https://github.com/maio/repro-jdbc-kotlin-lazy-embedded-problem.

./gradlew test

@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 Jun 21, 2024
@mp911de
Copy link
Member

mp911de commented Jun 24, 2024

Kotlin lazy introduces a delegate field that we discover as property. We already have precedence for Groovy's MetaClass as an exclusion rule. However, Kotlin never ceases to surprise in how they generate bytecode to achieve their goals while breaking framework support.

FWIW, here's the decompiled output:

public final class com/example/demo/Money {
     <ClassVersion=65>
     <SourceFile=DemoApplicationTests.kt>

     private final int amount;
     private final java.lang.String currency;
     private final kotlin.Lazy foo$delegate;
…

@mp911de mp911de added for: team-attention An issue we need to discuss as a team to make progress type: enhancement A general enhancement and removed status: waiting-for-triage An issue we've not yet triaged for: team-attention An issue we need to discuss as a team to make progress status: feedback-provided Feedback has been provided labels Jun 24, 2024
@mp911de mp911de self-assigned this Jun 24, 2024
@mp911de mp911de transferred this issue from spring-projects/spring-data-relational Jun 24, 2024
@mp911de mp911de added this to the 3.2.8 (2023.1.8) milestone Jun 24, 2024
@mp911de mp911de changed the title Kotlin lazy properties breaks @Embedded column type Kotlin lazy property identified as persistent entity Jun 24, 2024
@mp911de
Copy link
Member

mp911de commented Jun 24, 2024

For the time being, please annotate the delegated property with @delegate:org.springframework.data.annotation.Transient to exclude it from the mapping metamodel.

mp911de added a commit that referenced this issue Jun 24, 2024
We now filter delegated properties (such as lazy) from being managed as persistent properties.

Closes #3112
mp911de added a commit that referenced this issue Jun 24, 2024
We now filter delegated properties (such as lazy) from being managed as persistent properties.

Closes #3112
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