jpa - example - Clase de datos kotlin+validación de bean jsr 303
jsr 303 validation example (1)
Debe usar los objetivos de Annotation use-site, ya que el valor predeterminado para una propiedad declarada en el constructor es apuntar a la anotación en el parámetro constructor en lugar del getter (que será visto por los hosts compatibles con JavaBeans) cuando haya múltiples opciones disponibles. El uso de una clase de data
puede ser inapropiado aquí ( vea la nota al final ).
@Entity data class User(
@Id
@GeneratedValue(strategy = javax.persistence.GenerationType.AUTO)
var id: Long? = null,
@get:Size(min=5, max=15) // added annotation use-site target here
val name: String
)
El objetivo de property
de los documentos de Kotlin puede parecer tentador, pero solo se puede ver desde Kotlin y no desde Java. Por lo general, get
hace el truco y no es necesario en el set
beans.
Los documentos describen el proceso como:
Si no especifica un destino de sitio de uso, el destino se elige de acuerdo con la anotación @Target de la anotación que se está utilizando. Si hay múltiples objetivos aplicables, se utiliza el primer objetivo aplicable de la siguiente lista:
- param
- propiedad
- campo
Y la anotación @Size
es:
@Target(value={METHOD,FIELD,ANNOTATION_TYPE,CONSTRUCTOR,PARAMETER})
Por lo tanto, dado que PARAMETER
es un objetivo válido, y hay múltiples objetivos disponibles (parámetro, campo, método [obtener / configurar]), elige PARAMETER
que no es lo que usted desea. Por lo tanto, para que un host JavaBean vea la propiedad, buscará al getter (las propiedades están definidas por el getter / setter y no el campo de respaldo).
En uno de los ejemplos de Java , muestra:
public class Book {
private String title;
private String description;
// ...
@NotEmpty(groups={FirstLevelCheck.class, Default.class})
@Size(max=30)
public String getTitle() {
return title;
}
// ...
}
Que coincide con nuestro uso de tenerlo en el getter. Si estuviera en el campo como muestran algunas de las anotaciones de validación, vea el field
uso del sitio. O si el campo también debe ser de acceso público, vea la anotación @JvmField en Kotlin.
NOTA: Como se menciona en las notas de otros, probablemente debería considerar NO usar una clase de data
para las entidades si usan una ID generada automáticamente, ya que no existirá para los nuevos objetos igual que para los objetos recuperados; y una clase de data
generará equals
y hashCode
para incluir todos los campos, incluidos los que no debería. Puedes leer la guía sobre esto en los documentos de Hibernate .
Estoy tratando de que Kotlin trabaje con la validación jsr 303 en un proyecto Spring-Data-Rest.
Dada la siguiente declaración de clase de datos:
@Entity data class User(
@Id
@GeneratedValue(strategy = javax.persistence.GenerationType.AUTO)
var id: Long? = null,
@Size(min=5, max=15)
val name: String
)
La anotación @Size no tiene ningún efecto aquí, lo que me permite guardar un usuario con un nombre de 1 carácter.
Funciona bien cuando se ejecuta el mismo ejemplo pero en una clase de Java en lugar de Kotlin.
Esto me hace pensar en un problema de Kotlin.
Gracias de antemano por su ayuda!