2016-10-28 11 views
2

========== UPDATE Validation API, ==========Котлин: не может получить аннотацию

, когда я изменить аннотацию к @get: NotNull, @get: Min и @get: Max, hibernate-validator может прочитать успех этих аннотаций.

Но что я все еще хочу знать:

почему аннотация к одобрению-интерфейсы API, такие как @NotNull, @Min и @Max не может быть использована на членах класса данных напрямую, а аннотации JPA могут быть? ???

========== пыльник происхождение вопрос ===========

, когда я пытался использовать аннотацию валидации API на классе данных, валидатор class (из hibernate-validator) не может получить аннотации, поэтому проверка не удалась.

я написал тестовый случай, которые включают в себя 3-х классы данных:

  • 1-ые один использовать JPA аннотации @column и @Id, которые могут быть успешно считаны тестом.
  • второй один использование валидации-апите аннотацию @NotEmpty, @ Мин, @ Макс на членах, эти аннотации не могут быть прочитаны тестом
  • третий один использование валидации-апите аннотацию @get: NotEmpty, @get: Мин @ get: Max, тестовый пример не может прочитать эти аннотации.

Цель и сохранение @column, @NotNull, @Min и @Max все: RUNTIME и FIELD

Итак, что произошло в заду? как я могу правильно использовать аннотации проверки?

вот тест:

import org.hibernate.validator.constraints.NotEmpty 
import org.junit.Test 
import javax.persistence.Column 
import javax.persistence.Id 
import javax.validation.constraints.Max 
import javax.validation.constraints.Min 
import kotlin.reflect.KFunction 
import kotlin.reflect.KProperty 
import kotlin.reflect.jvm.javaField 
import kotlin.reflect.jvm.javaMethod 

class KotlinFeatureTest2 { 
    @Test 
    fun test_get_annotation() { 
     // can get field's annotation for BeanUseJPAAnnotation success 
     println("Getting field annotations for BeanUseJPAAnnotation :") 
     BeanUseJPAAnnotation::class.members.forEach { 
      if (it is KProperty) { 
       val field = it.javaField 
       println("${field?.name}'s annotations:") 
       field?.annotations?.forEachIndexed { i, an -> 
        println("  $i is: $an") 
       } 
      } 
     } 

     println("--------------------") 
     println("Getting field annotations for BeanUseValidationAnnotation :") 
     // CANT get field's annotation for BeanUseJPAAnnotation success 
     BeanUseValidationAnnotation::class.members.forEach { 
      if (it is KProperty) { 
       val field = it.javaField 
       println("${field?.name}'s annotations:") 
       field?.annotations?.forEachIndexed { i, an -> 
        println("  $i is: $an") 
       } 
      } 
     } 

     println("--------------------") 
     println("Getting field annotations for BeanUseValidationAnnotationOnMethod :") 
     // CANT get field's annotation for BeanUseJPAAnnotation success 
     BeanUseValidationAnnotationOnMethod::class.members.forEach { 
      if (it is KFunction) { 
       val method = it.javaMethod 
       println("${method?.name}'s annotations: ") 
       method?.annotations?.forEachIndexed { i, an -> 
        println("  $i is: $an") 
       } 
      } 
     } 
    } 
} 

data class BeanUseJPAAnnotation(
     @Column(name = "id") @Id val id: String, 
     @Column(name = "user_name") val name: String) 

data class BeanUseValidationAnnotation(
     @NotEmpty(message = "name can not be empty") 
     val name: String, 

     @Min(value = 1) 
     @Max(value = 100) 
     val age: Int 
) 

data class BeanUseValidationAnnotationOnMethod(
     @get:NotEmpty(message = "name can not be empty") 
     val name: String, 

     @get:Min(value = 1) 
     @get:Max(value = 100) 
     val age: Int) 

и здесь выход этого теста:

Getting field annotations for BeanUseJPAAnnotation : 
id's annotations: 
    0 is: @javax.persistence.Column(nullable=true, unique=false, precision=0, name=id, length=255, scale=0, updatable=true, columnDefinition=, table=, insertable=true) 
    1 is: @javax.persistence.Id() 
name's annotations: 
    0 is: @javax.persistence.Column(nullable=true, unique=false, precision=0, name=user_name, length=255, scale=0, updatable=true, columnDefinition=, table=, insertable=true) 
-------------------- 
Getting field annotations for BeanUseValidationAnnotation : 
age's annotations: 
name's annotations: 
-------------------- 
Getting field annotations for BeanUseValidationAnnotationOnMethod : 
component1's annotations: 
component2's annotations: 
copy's annotations: 
equals's annotations: 
hashCode's annotations: 
toString's annotations: 
+0

UPDATE: когда я изменить аннотацию «@get: NotNull», «@get: Min» и «@get: Max», hibernate-validator может прочитать успех этих аннотаций. Но я все еще хочу знать: почему аннотации validation-api, такие как «@NotNull», «@Min» и «@Max», нельзя использовать непосредственно для членов класса данных, в то время как аннотации JPA могут быть ???? –

ответ

1

Ниже подпись часть javax.persistence.Column:

@Target({METHOD, FIELD}) 
@Retention(RUNTIME) 
public @interface Column { 

Напротив, здесь та же самая часть javax.validation.constraints.Min:

@Target({ METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER, TYPE_USE }) 
@Retention(RUNTIME) 
@Repeatable(List.class) 
@Documented 
@Constraint(validatedBy = { }) 
public @interface Min { 

Как вы можете видеть аннотации JPA Постоянство цель METHOD и FIELD следовательно Котлин излучает их на FIELD уровне. Однако аннотации API валидаторов нацелены на большее количество конструкций, в частности PARAMETER. Учитывая, что при генерации аннотаций для объявленных свойств конструктора компилятор Kotlin выбирает только аннотировать только.BeanUseValidationAnnotation конструктор подписи эквивалент в Java будет выглядеть так:

public BeanUseValidationAnnotation(@NotEmpty(message = "name can not be empty") @NotNull String name, @Min(1L) @Max(100L) int age) { 

Такое поведение указано in the documentation:

Если вы не указали цель на месте применения, цель выбирается в соответствии к @Target аннотация используемой аннотации. Если есть несколько применимых целей, первая применимая цель из следующих списка используется:

  • param
  • property
  • field
+0

спасибо за ваше замечательное объяснение, которое делает вещи понятными ~ –

Смежные вопросы