Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Spring constructor annotations on Kotlin data class with default values

Tags:

spring

kotlin

To use spring persistence but maintain immutable types I've added the PersistenceConstructor annotation to my data classes. This tells spring to use that constructor when loading classes from the database.

However, I'm having trouble getting spring to find the constructor.

data class MyData @PersistenceConstructor constructor(@Id val id: Int? = null, val a:String)

This works 100% of the time on my machine but when deployed to heroku it consistently fails.

It looks like, by having default values for parameters kotlin generates more than one constructors but the problem is that each constructor get the annotation applied to them so it's just luck (or jdk implementation specific) which one spring picks up. The default one has no names for the parameters so Spring doesn't know what to do with it.

My real constructors are larger than this so it would be a pain to not have default values. Is there a way to get the annotation to only apply to the constructor without default values?

like image 826
Lionel Port Avatar asked Dec 19 '22 00:12

Lionel Port


1 Answers

You can use the @JvmOverloads annotation and this will automatically create permutations of the method that can be called by Java and also take advantage of the default values.

From the docs, this example:

@JvmOverloads fun f(a: String, b: Int = 0, c: String = "abc") {
    ...
}

will be seen from Java as:

// Java
void f(String a, int b, String c) { }
void f(String a, int b) { } // will default c
void f(String a) { } // will default b and c

Your case is a touch different where you have a defaulted parameter followed by one that is not. Simplifying your example to:

data class MyData @JvmOverloads constructor(val id: Int? = null, val a:String)

produces this view from Java:

// java
MyData(Int id, String a)
MyData(String a)  // defaults id

You can read more about Java calling Kotlin interoperability in the Kotlin reference.

like image 60
Jayson Minard Avatar answered May 23 '23 06:05

Jayson Minard