Today I created some JavaFX based UI by using hibernate-validator 6.0.0.Beta1
This version was released today and already integrates the support for the JavaFX
ListProperty. I created a PR for all the samples
(
https://github.com/hibernate/hibernate-demos/pull/24).
While doing the samples I found a problem in JBV 2.0 in combination with Collections. From
my point of view at least one general (maybe Provider based) method for validation is
missing in the Validator class. I created an issue:
https://hibernate.atlassian.net/browse/BVAL-622
Since the issue contains the description simply copy it:
I wrote some JavaSE sample to test the new ValueExtractor classes for JavaFX like
ListPropertyValueExtractor. In that case I miss an important feature in the base API.
Let's say I have a model that has the following fields:
@NotEmpty(message = "Name sollte nicht leer sein!")
private final StringProperty name = new SimpleStringProperty();
private final Property<@Min(50) Integer> count = new
SimpleObjectProperty<>();
@Size(min=1, max=4)
private final ListProperty<@Size(min=2, max=32) String> tags = new
SimpleListProperty<>(FXCollections.observableArrayList());
Next I bind all the properties of the model to UI nodes. Example:
nameField.textProperty().bindBidirectional(model.nameProperty());
In addition I want to do a validation call whenever a value in the model changes. For the
name property this can be done by the following code:
nameErrorNode.visibleProperty().bind(Bindings.createBooleanBinding(() ->
!validator.validateProperty(model, "name").isEmpty(),
model.nameProperty()));
By doing it like this only the name property will be validated whenever it changes. It
would be wrong to validate the complete model in this case.
I can simply do the same for the list:
tagErrorNode.visibleProperty().bind(Bindings.createBooleanBinding(() ->
!validator.validateProperty(model, "tags").isEmpty(),
model.tagsProperty()));
In this case the list will be validated whenever the list changes. This happens for
example if a new element will be added, updated or removed. Let's imagine a list with
1_000_000 entries or so. In that case I do not want to validate the complete list when I
update an element. Based on this I think that an additional method next to
Validator.validateProperty()
is needed in the JBV Spec to validate internal elements.
Am 21.04.2017 um 08:31 schrieb Gunnar Morling
<gunnar(a)hibernate.org>:
Right, it's an issue with parallel class hierarchies in general. The
same could happen during constraint validator resolution. In both
cases an extractor (or validator) for the specific sub-type must be
provided to resolve the ambiguity. This would also address your case
of cached and real value.
Based on the preference of option 2), I've added this to the pending
PR in the section on built-in extractors:
===
Compatible implementations provide value extractors for the following
types out of the box:
[...]
* javafx.beans.observable.ObservableValue; value() must be invoked
with the observable value, passing null as node name; the extractor
must be marked with @UnwrapByDefault
* javafx.beans.property.ReadOnlyListProperty and
javafx.beans.property.ListProperty; indexedValue() must be invoked for
each contained element, passing the string literal <iterable element>
as node name
* javafx.beans.property.ReadOnlyMapProperty and
javafx.beans.property.MapProperty; both map keys and map values are to
be supported; keyedValue() must be invoked by the map key extractor
for each contained key, passing the string literal <map key> as node
name; keyedValue() must be invoked by the map value extractor for each
contained value, passing the string literal <map value> as node name
===
2017-04-19 14:42 GMT+02:00 Hendrik Ebbers <hendrik.ebbers(a)me.com>:
> I think this is not a JavaFX specific problem. This can happen everywhere if
> you have defined extractors for 2 interface types and and have an
> implementation of both.
> In this specific example I would prefer to define ListProperty as a List.
>
> In general I think that this problem might / will happen in other frameworks
> and APIs, too.
>
> I added such an example in a mail about the usage of annotations in the
> generic information:
>
> Until now I only worked with lists and here the approach is quite nice.
> Sadly it won’t work always. By adding an constraints annotation to the
> generic type of the list we know that the annotation mentions the content of
> the list. But this is only working because of one point: The generic type of
> a collection defines the type of the collection content. This works fine for
> collections (and for example JavaFX properties) but in other cases this will
> end in problems.
>
> Let’s say we have the following 2 interfaces:
>
> public interface CachedValue<V> {
> V getCachedValue();
> }
>
> public interface RealValue<V> {
> V getRealValue();
> }
>
> Based on this interfaces we can easily create a new class that implements
> both interfaces:
>
> public class CachableValue<V> implements CachedValue<V>,
RealValue<V> {
>
> private V cachedValue;
>
> @Override
> public V getCachedValue() {
> return cachedValue;
> }
>
> @Override
> public V getRealValue() {
> V realValue = receiveValueFromServer();
> cachedValue = realValue;
> return realValue;
> }
>
> private V receiveValueFromServer() {
> return ServerConnector.getCurrentValue(); //Some fake code
> }
> }
>
>
>
>
> Am 18.04.2017 um 14:57 schrieb Emmanuel Bernard <emmanuel(a)hibernate.org>:
>
> I'm not using JavaFX but I would be in favor of 2. because it let's
> people put a size constraint on the List.
>
> Have you considered a blog post to get more feedback. Here people don't
> use JavaFX or are shy.
>
> On Wed 17-04-12 16:16, Guillaume Smet wrote:
>
> Hi,
>
> We are refining the value extraction work and one of the remaining tasks is
> to throw a proper exception if we have ValueExtractors defined in parallel
> hierarchies for a given type.
>
> This led to discovering the below issue with the JavaFX collection types.
>
> Let's take the ListProperty example (we have the same issue with Set and
> Map): ListProperty inherits from ObservableValue and from List.
>
> For now, it uses (by chance) the ObservableValue extractor which unwraps
> the value by default. So basically:
> @NotNull
> private ListProperty<String> listProperty = new
> ReadOnlyListWrapper<String>( null );
> will return a violation.
>
> With the new conflict detection, it will throw an exception as it's unable
> to find ONE most specific ValueExtractor as there are 2 valid candidates:
> ObservableValueValueExtractor and ListValueExtractor.
>
> If we want to solve the conflict, we need to introduce a specific
> ValueExtractor for ListProperty and decide of its behavior.
>
> We have 2 possibilities:
> 1/ consider ListProperty as an ObservableValue and thus simply unwrap the
> list and validate the constraint against the list. In the above example,
> @NotNull would then apply to the inner list. Same behavior as explained
> above.
> 2/ consider ListProperty as a List. Thus the value extractor would iterate
> over the element of the list. In the above case, it won't return a
> violation. In the below example, the @NotNull would refer to listProperty
> itself and the constraints on the elements of the list would be validated:
> @NotNull
> private ListProperty<@Size(min = 3) String> listProperty = new
> ReadOnlyListWrapper<String>( null );
>
> Gunnar and I are in favor of 2/ but it changes the current behavior as the
> @NotNull would refer to the container instead of referring to the wrapped
> value.
>
> We would really like to have some feedback from people using JavaFX.
>
> Thanks!
>
> --
> Guillaume
>
>
> _______________________________________________
> beanvalidation-dev mailing list
> beanvalidation-dev(a)lists.jboss.org
>
https://lists.jboss.org/mailman/listinfo/beanvalidation-dev
>
>
> _______________________________________________
> beanvalidation-dev mailing list
> beanvalidation-dev(a)lists.jboss.org
>
https://lists.jboss.org/mailman/listinfo/beanvalidation-dev
>
>
>
> _______________________________________________
> beanvalidation-dev mailing list
> beanvalidation-dev(a)lists.jboss.org
>
https://lists.jboss.org/mailman/listinfo/beanvalidation-dev
_______________________________________________
beanvalidation-dev mailing list
beanvalidation-dev(a)lists.jboss.org
https://lists.jboss.org/mailman/listinfo/beanvalidation-dev