1
votes

I am using Grails version 2.3.3, and groovy version 2.1.8.

I am using an online tutorial to help learn Grails web dev, and I have created a domain class with the following constraints

package racetrack



class Race {

static constraints = {
    name(blank:false, maxSize:50)
    city(blank:false)
    state(inList:["GA", "NC", "SC", "VA"])
    startDate()
    distance(min: 0.0) 
    cost(min: new BigDecimal(0.0), max: new BigDecimal(100.0))
    maxRunners(min:0, max:100000)
}

String name
Date startDate
String city
String state
BigDecimal distance
BigDecimal cost 
Integer maxRunners

}

I'm using scaffolding so I have full CRUD functionality. The problem is, when I go to create a new Race, the app allows me to input values like "-1" in both the distance and cost fields, and values like "200" for the cost field. I noticed that the Integer field maxRunners was working correctly, as it displays a warning message if I try to put in -1 maxRunners. I changed the cost field to be of type Integer, and then the constraints started working.

Why is this happening? I copy and pasted the code from the tutorial into my text file and the constraints to not work for BigDecimal type fields.

2

2 Answers

1
votes

According to the docs for the min and max constraints, the parameter must be

a class that implements java.lang.Comparable. The type of the value must be the same as the property.

so I can't see any reason why your definition shouldn't work. As a workaround, you could try replacing this

cost(min: new BigDecimal(0.0), max: new BigDecimal(100.0))

with

cost(range: 0..100)

and you could replace this constraint:

distance(min: 0.0)

with a custom validator, e.g.

distance validator: {
    it >= 0.0
}

I've just noticed the following oddity which appears before the 2 problematic constraints

startDate()

Perhaps replacing it with either:

startDate(nullable: true)

or

startDate(nullable: false)

might fix the problem?

1
votes

Doesn't Groovy use java.math.BigDecimal by default? Could you change new BigDecimal(0.0) to simply 0.0 and new BigDecimal(100.00) to 100.00 like this:

cost(min: 0.0, max: 100.0)

Here is the documentation that states:

To support the 'least surprising' approach, groovy literals with decimal points are instantiated as java.math.BigDecimal types rather than binary floating point types (Float, Double).

Also, you could try forcing it by using the G suffix like this:

cost(min: 0.0G, max: 100.0G)