kotlin data class + Bean validation jsr 303

Próbuję nakłonić Kotlina do pracy z JSR 303 validation nad projektem spring-data-rest.

Podano następującą klasę danych declaration:

@Entity data class User(
    @Id 
    @GeneratedValue(strategy = javax.persistence.GenerationType.AUTO)
    var id: Long? = null,

    @Size(min=5, max=15)
    val name: String
)

Adnotacja @Size nie ma tutaj żadnego wpływu, dzięki czemu mogę zapisać użytkownika o nazwie 1 znaku.
Działa dobrze, gdy wykonujemy ten sam przykład, ale w klasie Java zamiast Kotlina.

To sprawia, że myślę o problemie z Kotlinem.

Z góry dzięki za pomoc !

Author: hotkey, 2016-03-07

1 answers

Musisz użyć adnotation use-site targets ponieważ domyślną właściwością zadeklarowaną w konstruktorze jest kierowanie adnotacji na parametrze konstruktora zamiast getter (które będą widoczne dla hostów zgodnych z JavaBeans), gdy dostępnych jest wiele opcji. Również użycie klasy data może być tutaj niewłaściwe ( patrz uwaga na końcu ).

@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
)

Cel property z dokumentów Kotlina może wyglądać kusząco, ale może tylko być widziane z Kotlina a nie z Javy. Zazwyczaj {[5] } robi sztuczkę i nie jest potrzebna na fasoli set.

Dokumenty opisują proces jako:

Jeśli nie określisz celu use-site, cel zostanie wybrany zgodnie z adnotacją @ Target używanej adnotacji. Jeżeli istnieje wiele mających zastosowanie celów, stosuje się pierwszy mający zastosowanie cel z poniższego wykazu:

  • param
  • własność
  • pole

A @Size adnotacja brzmi:

@Target(value={METHOD,FIELD,ANNOTATION_TYPE,CONSTRUCTOR,PARAMETER})

Dlatego, ponieważ PARAMETER jest prawidłowym celem i dostępnych jest wiele celów (parametr, pole, metoda [get/set]), wybiera PARAMETER, co nie jest tym, czego chcesz. Dlatego, aby host JavaBean mógł zobaczyć właściwość, będzie szukał gettera (właściwości są zdefiniowane przez getter/setter, a nie Pole zapasowe).

W Jednym z próbek Java pokazuje:

public class Book {
    private String title;
    private String description;

    // ...

    @NotEmpty(groups={FirstLevelCheck.class, Default.class})
    @Size(max=30)
    public String getTitle() {
        return title;
    }

    // ...
}

Co odpowiada naszemu wykorzystaniu posiadania to na getter. Jeśli miałoby to znajdować się na polu, Jak pokazują niektóre adnotacje walidacji, zobacz cel field use-site. Lub jeśli pole musi być również publicznie dostępne, zobacz adnotację @JvmField w Kotlinie.

Uwaga: Jak wspomniano w notatkach od innych, prawdopodobnie powinieneś rozważyć Nie używanie klasy data dla encji, jeśli używają one automatycznie wygenerowanego identyfikatora, ponieważ nie będzie ona istnieć dla nowych obiektów tak samo jak dla odzyskanych obiektów; oraz data Klasa wygeneruje equals i hashCode, aby uwzględnić wszystkie pola, w tym te, których nie powinna. Możesz przeczytać wskazówki na ten temat z dokumentów Hibernate .

 35
Author: Jayson Minard,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-02-19 16:23:01