I am trying to implement some command object validation, but one property of command object is not binding its always return null
Domain class
package ni.sb
class PurchaseOrder implements Serializable {
Date dateCreated
Date dutyDate
String invoiceNumber
BigDecimal balance
String typeOfPurchase
Date lastUpdated
static constraints = {
dutyDate nullable:false, validator: { dutyDate ->
def today = new Date()
if (dutyDate <= today) {
"notMatch"
}
}
invoiceNumber blank:false, unique:true
balance nullable:true
typeOfPurchase inList:["Contado", "Credito"], maxSize:255
}
}
This is the command object
class PurchaseOrderCommand implements Serializable {
Date dutyDate
String invoiceNumber
String typeOfPurchase
static constraints = {
importFrom PurchaseOrder
}
}
Here is the controller action
def actName(PurchaseOrderCommand cmd) {
if (cmd.hasErrors()) {
println params.dump()
println cmd.dump()
return
}
}
dutyDate is not binding, after i try dumb() in params and cmd i get this
snippet params.dump()
dutyDate:2014-09-25
snippet cmd.dump()
dutyDate=null
I hope you can help me
If you inspect cmd.errors I expect you will see the error there.
If your date request parameters are formatted like "2014-09-25" and you are using a recent version of Grails then something like this should work:
import org.grails.databinding.BindingFormat
class PurchaseOrderCommand implements Serializable {
#BindingFormat('yyyy-MM-dd')
Date dutyDate
String invoiceNumber
String typeOfPurchase
}
Alternatively you could set "yyyy-MM-dd" as one of the default formats in Config.groovy.
// grails-app/conf/Config.groovy
grails.databinding.dateFormats = ['yyyy-MM-dd',
'MMddyyyy',
'yyyy-MM-dd HH:mm:ss.S',
"yyyy-MM-dd'T'hh:mm:ss'Z'"]
// ...
I hope that helps.
Related
I'm having a weird error caused by a many-to-many relationship between two domain classes. The classes are below. When I try to save the NoteParagraph object, I DON'T immediately get an error:
NoteParagraph np = new NoteParagraph(number: noteNumber, content: noteText)
note.addToChildParagraphs(np).save()
However, on the next .save() action (on an unrelated object), I get the following error stacktrace:
Field 'note_paragraph_id' doesn't have a default value. Stacktrace follows:
java.sql.SQLException: Field 'note_paragraph_id' doesn't have a default value
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:998)
at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3847)
at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3783)
at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:2447)
at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2594)
at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2545)
at com.mysql.jdbc.PreparedStatement.executeInternal(PreparedStatement.java:1901)
at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:2113)
at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:2049)
at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:2034)
at org.grails.datastore.gorm.GormStaticApi$_methodMissing_closure2.doCall(GormStaticApi.groovy:102)
Here are my classes:
class NoteParagraph {
String number
String content
Note parentNote
Date dateCreated
Date lastUpdated
static belongsTo = Note
static hasMany = [
childNotes: Note
]
static constraints = {
}
static mapping = {
content type:'text'
}
}
and the second one:
class Note {
Integer noteType
Integer parentType
Integer parentId
String heading
Date dateCreated
Date lastUpdated
static hasMany = [
childParagraphs: NoteParagraph
]
static constraints = {
}
static mapping = {
heading type:'text'
}
}
I've tried deleting and recreating my database as some other threads have suggested, and that did not help.
Fix:
class NoteParagraph {
String number
String content
Date dateCreated
Date lastUpdated
static belongsTo = [parentNote: Note]
static hasMany = [
childNotes: Note
]
static constraints = {
}
static mapping = {
content type:'text'
}
}
When you try to add NoteParagraph to Note, NoteParagraph instance is not persistent (it is created but not saved in db yet).
Try to change:
NoteParagraph np = new NoteParagraph(number: noteNumber, content: noteText)
note.addToChildParagraphs(np).save()
to:
note.save(flush: true) //add also this, if note is not persisted
NoteParagraph np = new NoteParagraph(number: noteNumber, content: noteText, parentNote: note).save(flush: true)
note.addToChildParagraphs(np).save()
I'm new to Grails and study it via InfoQ's "Getting Started With Grails" book.
Running through it I've faced a problem with the BootStrap.groovy file:
I've edited it as the book says.
Run-app it - and the data I've entered into BootStrap.groovy has been shown.
I've updated the bootstrapping values but they are not changed.
No errors are shown in the console.
What I've tried:
exchanging def's places;
set Runner's class value to nullables;
changed .save(failOnError:true) to .save(flush:true).
Even after I've changed the Race class' bootstrapping values it looks like it hasn't been changed.
Looks like the value is taken from somewhere else than the BootStrap.groovy?
I use Grails 2.2.1 with a PostgreSQL DB.
The classes' code is below:
package racetrack
class Runner {
static constraints = {
firstName(blank:false)
lastName(blank:false)
dateOfBirth(nullable:true)
gender(inList:["M","F"])
address(nullable:true)
city(nullable:true)
state(nullable:true)
zipcode(nullable:true)
email(email:true)
}
static hasMany = [registrations:Registration]
/*static mapping = {
sort "email"
}*/
String firstName
String lastName
Date dateOfBirth
String gender
String address
String city
String state
String zipcode
String email
String toString(){
"${firstName} ${lastName} (${email})"
}
}
and
package racetrack
class BootStrap {
def init = { servletContext ->
def begun = new Runner(firstName:"Marathon",
lastName:"Runner",
dateOfBirth:"",
gender:"M",
address:"",
city:"",
state:"",
zipcode:"",
email:"me#me.ru"
)
begun.save(flush:true)
def zabeg = new Race(name:"Run SPB",
startDate:new Date() + 360*30,
city:"Moscow",
state:"Moscow",
cost:10.0,
distance:42.0,
maxRunners:10)
zabeg.save(flush:true)
}
def destroy = {
}
}
EDIT: could this be happening due to any generate-* scripts been run?
Race.groovy:
package racetrack
class Race {
static hasMany = [registrations:Registration]
String name
Date startDate
String city
String state
BigDecimal distance
BigDecimal cost
Integer maxRunners
static constraints = {
name(blank:false, maxSize:50)
startDate(validator: {
return (it >= new Date())
}
)
city()
state(inList:["Moscow", "Volgograd", "SPb", "NN"])
distance(min:0.0)
cost(min:0.0, max:100.0)
maxRunners(min:0, max:100000)
}
static mapping = {
sort "startDate"
}
BigDecimal inMiles(){
return distance*0.6214
}
String toString(){
return "${name}, ${startDate.format('MM/dd/yyyy')}"
}
}
BootStrap should be in grails-app/conf instead. Refer this.
Try to print the errors of the new instance you save by adding
print begun.errors
See if somethings comes up.
You need to remove
def index() { }
from the controllers.
I had the same issue. Now it is fixed.
I have textfield for birthDate. When a user enter invalid date, let say for example a String, error message successfully displayed as fielderror. But in my console, I got this error:
java.lang.NoSuchMethodException: Profile.setBirthDate([Ljava.lang.String;)
Have I missed something that's why I encountered the error?
In your Action class you dont have a method called setBirthDate(String birthDate), add it your issue should be resolved.
Note check to see that you have placed all getter and setter in your action class for all properties.
I think in your JSP you have :
<s:textfield name="birthDate" />
Struts will try to map this to setBirthDate(String string), since this method is missing in your action hence the NoSuchMethodException
Update:
To convert String to Date:
public class MyStringToDateConverter extends StrutsTypeConverter {
public Object convertFromString(Map context, String[] values, Class toClass) {
//Parse String to get a date object
}
public String convertToString(Map context, Object o) {
// Get the string from object o
}
}
If you are using Annotation in your action class then add #Conversion() to your action
#Conversion()
public class MyAction extends ActionSupport{
public Date myDate = null;
#TypeConversion(converter="MyStringToDateConverter") //Fully qualified name so if this class is in mypackage then converter will be "myPackage.MyStringToDateConverter"
public void setMyDate(Date date) {
this.myDate = date;
}
}
If you dont want to use Annotation then you can look at the official documentation for example.
I have a custom toString method in my enum:
enum TaxRate implements Serializable {
RATE23(23.0),
...
private String s
private BigDecimal rate
private TaxRate(BigDecimal s) {
this.s = s + "%"
this.rate = s * 0.01
}
public String toString() {
return s
}
Now when I display the rates in HTML I get nice output like TAX: 23.0%.
But what happens when a user selects the tax from a <select> and the sent value is i.e. 23.0% is that Grails can't create/get the TaxRate instance...
What should I override to support this custom mapping? Trying to override valueOf(String) ended with a error..
Have you seen the entry at the bottom of this page?
If you want to use a Enum with a "value" String attribute (a pretty common idiom) in a element, try this:
enum Rating {
G("G"),PG("PG"),PG13("PG-13"),R("R"),NC17("NC-17"),NR("Not Rated")
final String value
Rating(String value) { this.value = value }
String toString() { value }
String getKey() { name() }
}
Then add optionKey="key" to your tag.
I have two Domain class in grails
class Quotation {
static searchable =true
static constraints = {
referenceNo(nullable:true)
dateOfRequest(validator: {return (it <= new Date())})
number(blank:false)
estimatedHours(nullable:true, blank:false, min:0)
}
int referenceNo;
Date dateOfRequest;
String number="11-120001Q01";
int estimatedHours;
String toString(){
return number
}
}
class Project {
static constraints = {
projectID(blank:false,nullable:false)
number(blank:true,nullable:true)
projectManager(blank:false)
teamLeader(blank:false)
teamMembers(blank:false)
sizeOfTeam(blank:false)
status(inList:["active", "closed"])
}
String projectID
Quotation number
String projectManager
String teamLeader
String teamMembers
Integer sizeOfTeam
String status
}
i want to print number and estimatedHours from Quotation class to be in Project class but it is only showing number.Can any one please tell me how to create an instance of Quotation in Project class and call the getter and setter methods of Quotation class?