4

I'm trying out some bean validation and I'm stumbling upon 'strange' behavior. I'm working with Glassfish and Primefaces as a front-end (if it makes any difference). Elsewhere in my project I use the Hibernate-validator, I'm not sure if it is validating JSF (else it is the default in Glassfish). I have a managed bean:

@javax.faces.bean.ManagedBean
@javax.faces.bean.ViewScoped
public class TestBean
{
    @Size(min=8)
    private String _testString;

    public String getTestString()
    {
        return _testString;
    }

    public String setTestString(String testString)
    {
        _testString = testString;
    }

    public void doSomethind()
    {
        // Do something with the test string
    }
}

And a JSF page containing this:

<h:form id="testForm">
    <h:outputLabel for="testInput" value="Input:"/>
    <p:inputText id="testInput" value="#{testBean.testString}"/>
    <p:message id="testInputMsg" for="testInput"/>
    <p:commandButton value="Aanmaken" action="#{testBean.doSomething}" update="@form"/>
</h:form>

The _testString does not get validated this way. However, bean validation does work when I change the field to:

@Size(min=8)
private String testString;

or when I annotate the getter in stead of the field:

private String _testString;

@Size(min=8)
public String getTestString()
{
    return _testString;
}

Following our coding guidelines, we must prefix private fields with an underscore. Which leaves me with one option; annotate the getter.

Could someone care to explain why it is behaving like this?

BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
siebz0r
  • 18,867
  • 14
  • 64
  • 107

1 Answers1

4

From the JSR 303 specification:

3.2. Constraint declaration

Constraint declarations are placed on classes or interfaces primarily through annotations. A constraint annotation (see Section 2.1), can be applied to a type, on any of the type's fields or on any of the JavaBeans-compliant properties.

(emphasis mine)

From the JavaBeans specification:

8.3.1 Simple properties

By default, we use design patterns to locate properties by looking for methods of the form:

public <PropertyType> get<PropertyName>();
public void set<PropertyName>(<PropertyType> a);

So, with a property name of _testString, it's looking for a getter/setter called get_testString() and set_testString() which doesn't exist in your case.

Your code guidelines conflicts the JavaBeans specficiation and hence JSR-303 bean validation simply won't work when you put the annotation on a property whose name conflicts the JavaBeans specification. JSR-303 can't find the getter/setter associated with the property name and hence won't be able to perform validation when they are called.

Either fix your code guidelines to comply the standards, or put the annotation on the getter instead and live with it. See further also the Standard Java Code Conventions.

Community
  • 1
  • 1
BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
  • Adjusting the coding guidelines is not possible. I guess annotating the getter will have to do. To bad this doesn't work though. Thanks for the explanation ;-) – siebz0r Jun 17 '12 at 21:27
  • 1
    You're welcome. I'd however report that they're making a big mistake with deviating from the Java Code Conventions. – BalusC Jun 17 '12 at 21:30
  • I would just code it as required by the JavaBeans Specification and say so in commentary to defend the 'deviation'. Not worth wasting any time over. – user207421 Jun 17 '12 at 21:33
  • @BalusC I stand by the coding guidelines. I'd rather say there is something wrong with the way the validation gets handled in JSF. We also use JPA and JAX-RS and this works fine (including the validation). A coding guideline should be free to choose, it shouldn't be a requirement to use the Java coding guidelines. – siebz0r Jun 17 '12 at 21:46