2016-03-07 14 views
15

Tôi đang cố gắng để Kotlin làm việc với xác nhận jsr 303 trong dự án phần còn lại của dữ liệu mùa xuân.lớp dữ liệu kotlin + xác thực bean jsr 303

Với lớp dữ liệu sau declarartion:

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

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

Các @size chú thích không có tác dụng ở đây, làm tôi có thể tiết kiệm một người dùng với một tên của 1 nhân vật.
Nó hoạt động tốt khi thực hiện cùng một ví dụ nhưng trong một lớp Java thay vì Kotlin.

Điều này khiến tôi nghĩ về vấn đề Kotlin.

Cảm ơn bạn đã trợ giúp!

+0

mục tiêu của chú thích là gì? Tham số constructor hoặc trường? – voddan

Trả lời

23

Bạn cần phải sử dụng Annotation use-site targets kể từ khi mặc định cho một tài sản được khai báo trong constructor được nhắm mục tiêu các chú thích trên các nhà xây dựng tham số thay vì getter (mà sẽ được nhìn thấy bởi JavaBeans host compliant) khi có nhiều tùy chọn có sẵn. Cũng sử dụng lớp học data có thể không phù hợp tại đây (xem ghi chú ở cuối).

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

Mục tiêu property từ tài liệu Kotlin có thể hấp dẫn nhưng chỉ có thể nhìn thấy từ Kotlin chứ không phải Java. Thông thường get thực hiện thủ thuật và không cần thiết trên bean set.

Các tài liệu mô tả các quá trình như:

Nếu bạn không chỉ định một mục tiêu sử dụng tại chỗ, mục tiêu được chọn theo chú thích @Target của chú thích được sử dụng. Nếu có nhiều mục tiêu áp dụng, mục tiêu áp dụng đầu tiên trong danh sách sau đây được sử dụng:

  • param
  • tài sản
  • lĩnh vực

@Size chú thích là:

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

Do đó kể từ PARAMETER là một mục tiêu hợp lệ, và nhiều mục tiêu có sẵn (tham số, trường, phương thức [get/set]) nó chosố PARAMETER mà không phải là những gì bạn muốn. Do đó đối với một máy chủ JavaBean để xem thuộc tính nó sẽ tìm kiếm getter (các thuộc tính được định nghĩa bởi getter/setter và không phải là trường sao lưu).

Trong một trong những Java samples, nó cho thấy:

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

    // ... 

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

    // ... 
} 

nào phù hợp với việc sử dụng của chúng tôi có nó trên getter. Nếu nó ở trên trường như một số chú thích xác thực hiển thị, hãy xem mục tiêu sử dụng field. Hoặc nếu trường này cũng phải có thể truy cập công khai, hãy xem @JvmField annotation trong Kotlin.

LƯU Ý:Như đã đề cập trong các ghi chú từ những người khác, bạn nên có khả năng xem xét không sử dụng một lớp data cho các tổ chức nếu họ sử dụng một ID tự động tạo ra vì nó sẽ không tồn tại cho các đối tượng mới giống như cho lấy các đối tượng; và một lớp học data sẽ tạo ra equalshashCode để bao gồm tất cả các trường bao gồm cả các trường không nên. Bạn có thể đọc hướng dẫn về điều này từ Hibernate docs.

+0

Bạn đá! Cảm ơn ! Cũng có thể sử dụng chú thích '@get: Size (min = 5, max = 15)'. – pellenberger

+2

Mặc dù câu trả lời đúng là đáng lưu ý là bạn không nên sử dụng 'lớp dữ liệu' cho thực thể. Lý do là - nó sẽ tạo ra các phương thức 'equals' và' hashCode' bằng cách sử dụng tất cả các thuộc tính, bao gồm 'id', không phải là hành vi mong muốn cho thực thể JPA. Xem tại đây: https://docs.jboss.org/hibernate/stable/core.old/reference/en/html/persistent-classes-equalshashcode.html – waste

+0

cảm ơn @waste, tôi đã chỉnh sửa để thêm ghi chú trực tiếp vào câu trả lời. –

Các vấn đề liên quan