Внедрете валидации в сетери или използвайте Hibernate Validator

Изправен съм пред дизайнерско решение в моя проект GWT + Hibernate.

Ще обясня въпроса си, като използвам дружество.

@Entity
@Table(name = "Company")
public class Company extends LightEntity implements BaseSerializable {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "Id")
    private int id;

    @Column(name = "Code")
    private String code;
    @Column(name = "Name")
    private String name;

    @Column(name = "Address")
    private String address;

    @Column(name = "ContactNumber1")
    private String contactNumber1;

    @Column(name = "ContactNumber2")
    private String contactNumber2;

    @Column(name = "EMail")
    private String email;

    @OneToMany(fetch = FetchType.LAZY, mappedBy = "company", cascade = CascadeType.ALL)
    private List<CompanyRegistration> companyRegistrations = new ArrayList<CompanyRegistration>();

    public Company() {
    }
    public Company(String code, String name) {
        this.setCode(code);
        this.setName(name);
    }

    // getters & setters
}

Валиден фирмен обект винаги трябва да има валиден код и име. Останалите свойства не са задължителни. Следователно, предоставих конструктор с два аргумента, за да гарантирам създаването на валиден обект.

Сега.

Свикнал съм да валидирам данни в сетери. Аз също използвам тези настройки в моите конструктори. Те гарантират, че нов обект винаги има валидно състояние. Това е/беше моят план за внедряване на обектите на Hibernate.

GWT-RPC обаче изисква конструктор noargs по подразбиране, така че да може да се използва за отложено свързване. Но това също ще позволи на всеки да създаде празен обект, което не е желателно в повечето от моите Hibernate обекти. Например, една компания винаги трябва да бъде изградена с код и име. Конструктор noargs противоречи на това правило.

Сега Hibernate е внедрил стандарт (JSR-303, ако паметта ми не ме изневерява) за рамка за валидиране. Позволява ви да извиквате валидации на вече създаден обект.

Проблемът ми възникна поради конструктора noargs. Ако не беше задължително, щях да премахна валидациите в сетера.

Ако внедря валидации в сетери, това означава, че невалиден обект ще се провали възможно най-бързо. Няма да е необходимо да извиквам проверка на обект от страна на клиента. Но празен обект (създаден с помощта на конструктора noargs) не може да бъде валидиран по този начин. Може да стигне до услугата, което означава, че трябва да внедря валидации, много от които може да са същите като сетерите, в слоя на услугата.

Ако внедря рамката за валидиране, тогава трябва да извикам валидиране на всеки обект, който създавам от страна на клиента. Ако забравя да валидирам такъв, той може да премине към сервизния слой в невалидно състояние. Мога обаче лесно да използвам същата рамка на слоя на услугата.

Едно решение, за което се сетих, е така или иначе да внедря валидации в сетерите, но също така да използвам Валидатор в слоя на услугата, преди да изпратя обект, който да остане в базата данни. По този начин клиентската страна ще бъде автоматично ограничена от сетерите. От друга страна, ако празен обект бъде изпратен така или иначе към страната на сървъра, той ще бъде уловен от Валидатора на сервизния слой. И в двата случая на потребителя ще бъде изпратено изключение.

Мисля обаче, че това не е най-доброто решение. И така, бих искал да взема един.

РЕДАКТИРАНЕ - Във всеки случай използвам анотации, за да поставя ограничения върху полетата на обекти, така че Hibernate да може да ги използва за валидиране, преди да запази обект.


person Jayesh Bhoot    schedule 04.02.2013    source източник


Отговори (1)


Ако проблемът ви произтича само от задължителния конструктор с нулев аргумент за GWT-RPC, имайте предвид, че можете да направите този конструктор недостъпен за разработчиците (дори private, ако искате); GWT-RPC ще получи достъп до него чрез отражение, независимо от неговата видимост.

person Thomas Broyer    schedule 04.02.2013
comment
добре, по дяволите! Никога не съм мислил за това. Току-що направих частен конструктор по подразбиране и той проработи! Предполагам, че това приключва проблема ми. Бих искал обаче да знам какво всъщност бихте предпочели да направите, ако това не беше единственият проблем. - person Jayesh Bhoot; 04.02.2013
comment
Реших да внедря валидации в сетери. С разрешаването на проблема с конструктора на noargs сега моето приложение винаги ще има валидно състояние за обект. Слоят на услугата все още ще има ненулево ограничение като валидиране. Въпреки това, аз също ще внедря анотации за ограничения на Hibernate към обектите, така че ако възникне нужда, ще мога да използвам Hibernate Validator в слоя на услугата за валидиране. - person Jayesh Bhoot; 04.02.2013