2017-02-27 124 views
0

我決定在實體中使用值對象而不是字符串字段,我不知道如何(以及是否有可能)使用@Size,@Pattern和JPA等註解來驗證它們等等。 這裏是我的書的實體:使用註釋驗證值對象

@Entity 
@Access(AccessType.FIELD) // so I can avoid using setters for fields that won't change 
public class Book { 

    @Id 
    @GeneratedValue(strategy = GenerationType.IDENTITY) 
    private Long bookId; 

    @Embedded 
    private Isbn isbn; 
    @Embedded 
    private Title title; 
    @Embedded 
    private Author author; 
    @Embedded 
    private Genre genre; 
    @Embedded 
    private PublicationYear publicationYear; 
    private BigDecimal price; 

    // jpa requirement 
    public Book() { 
    } 

    public Book(Isbn isbn, Title title, Author author, Genre genre, PublicationYear publicationYear, 
     BigDecimal price) { 
    this.isbn = isbn; 
    this.title = title; 
    this.author = author; 
    this.genre = genre; 
    this.publicationYear = publicationYear; 
    this.price = price; 
    } 

    public Long getBookId() { 
    return bookId; 
    } 

    public Isbn getIsbn() { 
    return isbn; 
    } 

    public Title getTitle() { 
    return title; 
    } 

    public Author getAuthor() { 
    return author; 
    } 

    public Genre getGenre() { 
    return genre; 
    } 

    public BigDecimal getPrice() { 
    return price; 
    } 

    public PublicationYear getPublicationYear() { 
    return publicationYear; 
    } 

    // setter for price is needed because price of the book can change (discounts and so on) 
    public void setPrice(BigDecimal price) { 
    this.price = price; 
    } 

} 

這裏是我的榜樣值對象 - 所有的只是使用字符串。

public class Isbn { 
    private String isbn; 

    // jpa requirement 
    public Isbn() { 
    } 

    public Isbn(String isbn) { 
    this.isbn = isbn; 
    } 

    public String getIsbn() { 
    return isbn; 
    } 

    @Override 
    public boolean equals(Object o) { 
    if (this == o) { 
     return true; 
    } 
    if (o == null || getClass() != o.getClass()) { 
     return false; 
    } 

    Isbn isbn1 = (Isbn) o; 

    return isbn != null ? isbn.equals(isbn1.isbn) : isbn1.isbn == null; 
    } 

    @Override 
    public int hashCode() { 
    return isbn != null ? isbn.hashCode() : 0; 
    } 

    @Override 
    public String toString() { 
    return "Isbn{" + 
     "isbn='" + isbn + '\'' + 
     '}'; 
    } 
} 

是否有一種簡單的方法來驗證這些對象?如果它是我實體中的字符串而不是Isbn對象,那麼我可以使用@Pattern來匹配正確的Isbn並完成它。

編輯1:也許有更好的方法來驗證比上面的值對象?我有點新東西,所以想知道是否有更好的選擇來驗證我的實體。

+0

他們每個本質上都是String的權利?爲什麼你需要爲每個類創建單獨的類?只需使用'javax'驗證註釋; http://www.baeldung.com/javax-validation –

+0

另外我建議使用'lombok'作爲getter/setter /構造函數的一代; https://projectlombok.org/ –

+1

嗯,這就是爲什麼你會使用值對象:將你的無意義的字符串交換到對象 - 有一個閱讀:https://martinfowler.com/bliki/ValueObject.html – doublemc

回答

1

您可以通過使用@Valid註釋來強制驗證Object字段;

@Entity 
@Access(AccessType.FIELD) 
public class Book { 

    @Embedded @Valid 
    private Isbn isbn; 
... 
} 

public class Isbn { 
    @Pattern(//Pattern you'd like to enforce) 
    private String isbn; 
... 
} 

然後你可以自己驗證使用以下;

ValidatorFactory factory = Validation.buildDefaultValidatorFactory(); 
Validator validator = factory.getValidator(); 
Set<ConstraintViolation<User>> violations = validator.validate(book); 
//if set is empty, validation is OK