Anotaciones de constructor de spring en la class de datos de Kotlin con valores pnetworkingeterminados

Para usar la persistencia de spring pero mantener los types inmutables, agregué la anotación PersistenceConstructor a mis classs de datos. Esto le dice a la spring que use ese constructor al cargar classs desde la database.

Sin embargo, estoy teniendo problemas para que la spring encuentre el constructor.

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

Esto funciona el 100% del time en mi máquina pero cuando se despliega en heroku falla sistemáticamente.

Parece que, al tener valores pnetworkingeterminados para los parameters, kotlin genera más de un constructor, pero el problema es que cada constructor obtiene la anotación que se les aplica, por lo que solo la suerte (o la implementación de jdk específica) es la que recoge un resorte. El pnetworkingeterminado no tiene nombres para los parameters, por lo que Spring no sabe qué hacer con él.

Mis constructores reales son más grandes que esto, así que sería un dolor no tener valores pnetworkingeterminados. ¿Hay alguna manera de hacer que la anotación solo se aplique al constructor sin valores pnetworkingeterminados?

Puede usar la anotación @JvmOverloads y esto creará automáticamente las permutaciones del método que Java puede @JvmOverloads y también podrá aprovechar los valores pnetworkingeterminados.

De los documentos, este ejemplo:

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

se verá desde Java como:

 // 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 

Su caso es un poco diferente donde tiene un parámetro pnetworkingeterminado seguido de uno que no lo está. Simplificando tu ejemplo a:

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

produce esta vista desde Java:

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

Puede leer más sobre Java llamando a la interoperabilidad de Kotlin en la reference de Kotlin.

Por el momento, mi respuesta actual es definir dos constructores. Uno para usarlo tiene valores pnetworkingeterminados y uno para usar en spring que no tiene valores pnetworkingeterminados.

 data class MyData @PersistenceConstructor constructor(val a: Int?, val b:String, val c : Collection<Int>) { constructor(a: Int? = null, b: String = "", c: Collection<Int> = emptyList()) : this(a,b,c) } 

No me gusta porque es una duplicación, así que no es mi solución preferida.

  • El file spring-configuration-metadata.json no se genera en IntelliJ Idea for Kotlin @ConfigurationProperties class
  • Enfoque correcto para la class de Kotlin inyectada de constructor inmutable
  • Excepción de puntero nulo en Spring Proxy Class y Kotlin
  • Kotlin y DynamoDBMapper SaveBehavior
  • El controller de exception Spring Boot @ControllerAdvice no se activa
  • no hay constructor pnetworkingeterminado para la entidad JPA con Kotlin, incluso con el complemento noarg
  • Spring Boot no puede ejecutar una testing individual en IntelliJ
  • Configuración de security de spring de Kotlin
  • Spring PropertySources cargado pero no aplicado en Pruebas
  • La desconnection no funciona en la aplicación Spring Boot (no es compatible con el método POST)
  • ¿Es posible usar Kotlin en Grails?