I'm attempting to use GroupSequenceProvider from hibernate bean validation in a JSF application but the getValidationGroups(T t) method in the assigned group sequence provider always receive a null argument so I can't use the state of the bean undergoing validation to dynamically create a sequence (which is what I was trying to accomplish).
When I submit the form in the example below @NotBlank(groups=TestGroup.class) for input2 will not be validated because that group is only added to the list when the argument of getValidationGroups is not null, which never happens.
Am I missing something? When testing the same setup of Data and TestSequenceProvider in a project with only hibernate-validator initiating the validation explicitly from a main method it works.
I'm using:
hibernate validator 5.2.3
JSF 2.2
Running on WildFly 10.0.0 Final
Example code:
Data.java
Code:
package test;
import java.io.Serializable;
import org.hibernate.validator.constraints.NotBlank;
import org.hibernate.validator.group.GroupSequenceProvider;
@GroupSequenceProvider(TestGroupSequenceProvider.class)
public class Data implements Serializable{
private static final long serialVersionUID = 1L;
@NotBlank(message="input1 (no group) validation failed")
private String input1;
@NotBlank(message="input2 (TestGroup) validation failed", groups=TestGroup.class)
private String input2;
/* Getters/Setters omitted */
}
TestGroupSequenceProvider.java
Code:
package test;
import java.util.ArrayList;
import java.util.List;
import org.hibernate.validator.spi.group.DefaultGroupSequenceProvider;
public class TestGroupSequenceProvider implements DefaultGroupSequenceProvider<Data> {
@Override
public List<Class<?>> getValidationGroups(Data data) {
List<Class<?>> groupSequence = new ArrayList<>();
groupSequence.add(Data.class);
if(data != null) {
groupSequence.add(TestGroup.class);
System.out.println("TestGroupSequenceProvider.getValidationGroups> Data is NOT null");
}
else {
System.out.println("TestGroupSequenceProvider.getValidationGroups> Data IS null");
}
return groupSequence;
}
}
DataView.java
Code:
package test;
import java.io.Serializable;
import javax.faces.view.ViewScoped;
import javax.inject.Named;
@Named
@ViewScoped
public class DataView implements Serializable{
private static final long serialVersionUID = 1L;
private Data data = new Data();
public void submit() {
System.out.println("DataView.submit()> Data [input1=\""+data.getInput1()+"\", input2=\""+data.getInput2()+"\"]");
if(data.getInput2()==null) {
System.out.println("DataView.submit()> Input2 == null");
}
}
public Data getData() {
return data;
}
}
test.xhtml
Code:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://xmlns.jcp.org/jsf/html">
<h:body>
<h:form>
Input1:
<h:inputText value="#{dataView.data.input1}" />
<br/>
Input2:
<h:inputText value="#{dataView.data.input2}" />
<br/>
<h:commandButton action="#{dataView.submit()}" value="Submit" />
<br/>
<h:messages />
</h:form>
</h:body>
</html>
TestGroup.java
Code:
package test;
public interface TestGroup {
}
Putting any text in input1 (or it will fail validation) and submitting the form by pressing the submit button results in the following printouts to the console:
11:58:35,029 INFO [stdout] (default task-6) TestGroupSequenceProvider.getValidationGroups> Data IS null
11:58:35,030 INFO [stdout] (default task-6) TestGroupSequenceProvider.getValidationGroups> Data IS null
11:58:35,032 INFO [stdout] (default task-6) TestGroupSequenceProvider.getValidationGroups> Data IS null
11:58:35,032 INFO [stdout] (default task-6) TestGroupSequenceProvider.getValidationGroups> Data IS null
11:58:35,034 INFO [stdout] (default task-6) DataView.submit()> Data [input1="asdf", input2="null"]
11:58:35,034 INFO [stdout] (default task-6) DataView.submit()> Input2 == null
So JSF validation stage passes and proceeds to call DataView.submit() because input2 is not validated.