JSR-303 Как по-разному проверить два дочерних объекта

Я использую Hibernate Validator в качестве реализации JSR-303.

Предположим, у меня есть:

class Form {
    @Valid
    private Owner mainOwner;
    @Valid
    private Owner secondOwner;
    // ... many other fields
}

class Owner {
    @DriverLicenseValid // some custom validation
    private String driverLicense;
    // ... many other fields
}

// ...

Form myForm;
validator.validate(myForm);

Видите, я хочу проверить всю форму, она содержит два похожих дочерних объекта типа Owner. Проблема в том, что для mainOwner driverLicense должно быть @NotNull, а для secondOwner — @Null.

Я не могу использовать здесь группы (можно?), так как вся модель проверяется одним вызовом validate(). Есть ли способ решить эту проблему, не записывая это правило как пользовательское ограничение на уровне формы?


person Rodion Gorkovenko    schedule 16.04.2013    source источник


Ответы (3)


Создайте аннотацию проверки в поле mainOwner в Form, которая подтверждает, что экземпляр Owner имеет установленные водительские права.

Аннотация @DriverLicenseValid должна просто следовать рекомендациям спецификации jsr-303 о том, что значения null действительны по умолчанию. Так что вам не нужно менять класс Owner.

person SpaceTrucker    schedule 16.04.2013
comment
Спасибо, но я спрашивал, можно ли этого добиться без настраиваемого ограничения на уровне формы, то есть над полем mainOwner. Возможно, я не сумел правильно выразить это. Однако, поскольку вы предлагаете то же решение, о котором я думал, я думаю, что другого пути нет. Хорошо, конечно, ScriptAssert подойдет, но это почти то же самое, что написать собственный валидатор. - person Rodion Gorkovenko; 16.04.2013
comment
@RodionGorkovenko Я не могу придумать другого разумного способа сделать это. Поэтому вы должны придерживаться своих первых мыслей. - person SpaceTrucker; 16.04.2013

Если вы работаете с Hibernate Validator 4.x, вы можете использовать собственный поставщик последовательности групп, как описано в этом сообщение на форуме.

person Gunnar    schedule 16.04.2013
comment
Не могли бы вы объяснить, как я могу использовать его для этого случая. Если я аннотирую класс Owner, то я получу только ссылку на экземпляр Owner в методе getValidationGroups. Я не мог сказать по этому экземпляру, ссылается ли на него mainOwner или secondOwner. Если я аннотирую саму Форму - я вообще не мог понять, что она дает для проверки Владельцев. Я извиняюсь за свою глупость. - person Rodion Gorkovenko; 17.04.2013
comment
Вам нужно будет передать состояние/роль экземплярам Owner, например. вот так: private Owner mainOwner = new Owner("main");. Затем в поставщике последовательности групп по умолчанию вы можете получить доступ к роли и вернуть правильную последовательность групп по умолчанию. - person Gunnar; 18.04.2013
comment
А, спасибо. хотя это определенно не то, что я хочу. В любом случае спасибо за полезную информацию. - person Rodion Gorkovenko; 18.04.2013
comment
Да, конечно, не идеально. Обратите внимание, что начиная с Bean Validation 1.1 вы сможете очень элегантно решить проблему, используя групповые конверсии. - person Gunnar; 19.04.2013

Используйте группы:

class Form {
    @Valid
    @ConvertGroup(from=Default.class, to=NotNullDriversLicense.class)
    private Owner mainOwner;
    @Valid
    @ConvertGroup(from=Default.class, to=NullDriversLicense.class)
    private Owner secondOwner;
    // ... many other fields
}

class Owner {
    @Null(groups = NullDriversLicense.class)
    @NotNull(groups = NotNullDriversLicense.class)
    private String driverLicense;
    // ... many other fields
}

interface NullDriversLicense {}
interface NotNullDriversLicense {}

// ...

Form myForm;
validator.validate(myForm);
person nevster    schedule 11.04.2019