3

I am attempting to validate a Double field with the help of Hibernate validation API - using @Digits annotation

<areaLength>0</areaLength>
<buildArea>0.0</buildArea>

@Digits(integer=10, fraction=0)
private Long areaLength = null; // Here areaLength = 0 

@Digits(integer=20, fraction=0)
private Double buildArea = null; // Here buildArea = 0.0

Here areaLength has no constraint violation,

but buildArea is getting a constraint violation, saying

buildArea numeric value out of bounds (<20 digits>.<0 digits> expected)

No violation for 10.0, But getting violation for 0.0.

Does anybody know the reason?

Full Code :

public class ValidationTest {

    public static void main(String a[]) {
        Vehicle vehBean = new Vehicle();
        try {
            if (vehBean != null) {
                ValidatorFactory factory = Validation.buildDefaultValidatorFactory();
                Validator validator = factory.getValidator();
                Set<ConstraintViolation<Vehicle>> violations = validator.validate(vehBean);
                if (violations!= null && violations.size() > 0) {
                    for (ConstraintViolation<Vehicle> violation : violations) {
                        System.out.println("Validation problem : " + violation.getMessage());
                    }
                }
            }
        } catch(Exception e) {
            throw e;
        }
    }
}

class Vehicle {
    @Digits(integer=20, fraction=0)
    private Double buildArea = 0.0; 
}

Validation problem : numeric value out of bounds (<20 digits>.<0 digits> expected)

deadend
  • 1,286
  • 6
  • 31
  • 52
  • @Digits only applicable to the BigDecimal, BigInteger, CharSequence, byte, short, int, long, and the respective wrappers of the primitive types. The `buildArea` is Double and hence, not working correctly. Besides, set the fraction=1 if you want to have 1 digit after the decimal point. – Arefe Dec 05 '20 at 07:08

4 Answers4

4

Alternatively, You can try;

@DecimalMin("0.00") 
@DecimalMax("99999999999999999.00") 
buræquete
  • 14,226
  • 4
  • 44
  • 89
Satt
  • 56
  • 3
  • This won't work since it will accept fraction values, that was restricted by OP – buræquete Mar 15 '17 at 04:14
  • 1
    I have tested, it is working for 0, 0.0, 10.0, 10.101. Getting violation for 99999999999999999999999999.00 – Satt Mar 15 '17 at 04:22
  • 1
    OP's requirement says no fraction is acceptable, how is `10.101` is OK? You have to have a violation with that saying "amount of fraction digits should be 0, but it was 3" – buræquete Mar 15 '17 at 04:23
  • I am using @ DecimalMin & Max instead of @ Digits for double types – Satt Mar 15 '17 at 04:35
3

You've restricted the amount of digits for fraction part to 0 meaning no fraction allowed, even though there isn't any in your 0.0 but you should confirm that that is the case, I think you have a Double value that is 0 < x < 0.1 You can also try using Float for the same field, and check if that has the same trouble?

The value of the field or property must be a number within a specified range. The integer element specifies the maximum integral digits for the number, and the fraction element specifies the maximum fractional digits for the number.

source

buræquete
  • 14,226
  • 4
  • 44
  • 89
  • Ok Noted bureaquete. Thanks for your answer. But if i give 10.0 instead of 0.0 with @Digits(integer=20, fraction=0). It getting pass. – deadend Mar 14 '17 at 13:38
  • @DEADEND I see, sorry for my answer, I hadn't tested or anything, when I test now all your cases are OK in my setup. I do not get any constraint violation for neither `0.0` nor `10.0`, I think the trouble you have is how those values are being set into the bean, somehow you might be getting an approximate number such as `0.000000001` for `0.0` and might trigger the violation. Can you debug and confirm it? – buræquete Mar 14 '17 at 13:54
  • private Double buildArea = 0.0; - Its fail. private Double buildArea = 10.0; - Its pass. Just i initialize like this and i have tested. – deadend Mar 14 '17 at 14:06
  • @ bureaquete hibernate-validator-4.1.0.Final. Please see my full code for your reference – deadend Mar 14 '17 at 14:09
  • @DEADEND nope, using your code directly, does not give any violation in my setup, can you also share your dependencies? – buræquete Mar 14 '17 at 14:15
  • @ bureaquete javax.validation-1.0.0.GA - This is dependency jar. – deadend Mar 14 '17 at 14:17
  • @DEADEND again same result, no violation, pretty weird, I cannot come up with any other reason. – buræquete Mar 14 '17 at 14:18
  • @ bureaquete. I am using java 7. But same code and jar's give me a violation. Thank you so much for your effort bureaquete. Please let me know if you have reproduced or find any other solution. – deadend Mar 14 '17 at 14:22
  • @DEADEND What I know is, the validator logic gets the String representation of the double value you supply, and that is evaluated for `@Digits` restrictions, when you use String type for `buildArea` you can see this. I cannot find a reason for difference on your setup between `0.0` and `10.0`, can you try using primitive `double`, and also `float` types & test again? – buræquete Mar 14 '17 at 15:03
  • @ bureaquete. double 0.0 - Fail, float 0 - Fail, long 0 - pass – deadend Mar 15 '17 at 04:09
  • @DEADEND why use `0` for float? Haven't you used `float buildArea = (float) 0.0` for it? And how could it fail for `0`? – buræquete Mar 15 '17 at 04:16
  • 1
    @ bureaquete float buildArea1 = (float) 0.0; - Fail. float buildArea1 = (float) 10.0; - Pass. float buildArea1 = 0; - Fail, double buildArea1 = 0; - Fail. – deadend Mar 15 '17 at 04:28
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/138073/discussion-between-bureaquete-and-deadend). – buræquete Mar 15 '17 at 04:31
  • Ok please ping me in chat. i really need your help for this. – deadend Mar 15 '17 at 04:36
1

I think the main problem here with buildArea is its datatype Double.

https://www.owasp.org/index.php/Bean_Validation_Cheat_Sheet

above link says the data type allowed by @Digits does not support Double.

Test
  • 11
  • 1
  • 1
    Welcome to Stack Overflow! Whilst this may theoretically answer the question, [it would be preferable](//meta.stackoverflow.com/q/8259) to include the essential parts of the answer here, and provide the link for reference. – Mat Oct 15 '18 at 10:38
1

I don't get it. If you have 1 digits in fraction part, like 0.0, why do you restrict in @Digits with fraction=0? That restriction wants to ensure that you have no decimals, so only integers are valid in your case.

This is valid:

@Digits(integer=10, fraction=1)
private Double double1 = 0.0;

This is valid, too:

@Digits(integer=10, fraction=0)
private Integer integer1 = 0;

But this is not valid:

@Digits(integer=10, fraction=0)
private Double double1 = 0.0; // Double not allowing a fraction part = integer, so you must change type here.
WesternGun
  • 11,303
  • 6
  • 88
  • 157