Trim domain field by default - grails

What is the best way to trim field value in domain?
My suggestion is to use beforeSave(), but would work something like this?
class Book {
String name = name?.trim()
}

You have a couple options depending on what behavior you want.
A custom setter, which will trim the value every time you set it
class Book {
String name
void setName(String name) {
this.name = name?.trim()
}
}
A custom getter, which will give you a trimmed value but not store it in the database
class Book {
String name
String getName() {
this.#name?.trim()
}
}
A hibernate event, like beforeSave() as you mentioned, which will only trim it before the object is persisted.

Well, you can enable automatic trimming of string in Grails (version 2.3+) by setting below property in Config.groovy file:
grails.databinding.trimStrings = true
This will automatic trim the string before save or update.

I have have noticed that Grails automatically does a .trim() on fields before persisting them. For example:
null
""
" "
All gets stored as null in Grails 2.3.7 for a nullable string. In addition:
" foobar "
gets stored as "foobar"
These results are using the default h2 database. So you might let Grails do the heavy lifting in this case.

Here is my hack for quickly trimming all fields in a domain object. I often receive JSON data that is not formatted in a way that would allow me to use data-binding techniques. This method can be called after updating or assigning all values in the domain instance.
class Book {
def trimFields() {
this.properties = this.properties
}
}
Requires this configuration which is set by default in Grails
grails.databinding.trimStrings = true
I know this is overkill but it's quick and easy to add to a domain class.

Related

Grails Criteria query with a condition on data

I have a database table storing data for this Grails domain class using vanilla GORM:
class A {
String propOver // may be null
String propBase
}
I want to create a search query that searches against the propOver property if it contains a value, otherwise against the propBase property. Or, to word this differently, propOver overrides propBase when it exists.
I need something that works like this pseudo-code:
def results = A.createCriteria().list{
if propOver isn't null: // the heart of the problem
eq('propOver', search_input)
else
eq('propBase', search_input)
}
Is it even possible?
Please note that one (bad) solution would be to create a 3rd property that stores the propOver ?: propBase value, but it violates the DRY principle, and I'd prefer avoiding modifying the DB.
This will do?
A.createCriteria().list{
or {
eq 'propOver', search_input
and {
isNull 'propOver'
eq 'propBase', search_input
}
}
}

Domain object string field auto trimming

After update from Grails 2.2.3 to Grails 2.3.5 (groovy 2.0.8->2.1.9) I found strange behavior
Domain object:
class Element {
String name
String title
static constraints = {
title nullable: true
}
}
During creation String field trims automatically and empty string replaced by null
def e = new Element(name:'', title:' sgg gg ')
assert e.name==null
assert e.title=='sgg gg'
I can't find this super feature in changelog of Grails & groovy. How I can disable it?
From: http://grails.1312388.n4.nabble.com/Grails-2-3-Data-Binding-String-Trimming-And-Null-Conversions-td4645255.html
The default behavior in Grails 2.3 is to trim strings during data binding. In addition to that, another default behavior is to convert empty strings (strings with nothing in them, not even spaces) to null during data binding. Those 2 things happen in that order so if you bind a String with nothing in it but spaces, the default behavior is to bind null because the String will be trimmed and then since it is empty it will be converted to null. This is a sensible default. There are separate config properties for disabling either of those behaviors.
// grails-app/conf/Config.groovy
grails.databinding.convertEmptyStringsToNull=false
grails.databinding.trimStrings=false
I believe it's mentioned here in the documentation

Property [] of class [] can not be null error in Grails

I am new to Grails and getting this error on two out of my three domains when I run the project on all the domains content. The domain the works is
class Location {
def scaffold = true
String company
String name
String address
static belongsTo=[company:Company]
static constraints = {
}
}
The domain that does not work is
class Report {
def scaffold = true
String title
String location
Date published
static belongsTo=[location:Location]
static constraints = {
}
}
I can not see the structural or syntax issue that is trowing the errors. I have been trying a variety of adds and subtracts and can not seem to find anything that address this error at a basic level. Again I have just started using Grails and Groovy
After doing the changes told by #araxn1d, you should also check the constraints. By default all properties are not nullable (that's why you're getting for example the error for the title property)
If you already have data in your database you have two options:
Update your database and set the correct values in each table or row
Set each property in the domain as nullable. For example
static constraints = {
title nullable:true
}
Are you creating a Report with no properties set? By default, Grails will check that all properties are not null. If you want to allow the user to leave a certain field undefined (null), then you have to explicitly tell Grails in the constraints map:
static constraints = {
propertyName nullable: true
}
Seems like error is in this line:
String location
location is String type, but should be Locationtype. The same as String company in Location domain should be Company company.
I think the problem is that you've changed the structure of the domain class after you generated the automatically created views/controller for the domain.
I fixed it by just deleting the offending domain along with the controller/views file and recreating them. I'm sure you could root through and find the offending code though.

domains have some common fields,extends domain or embedded?

when i design database.I use embedded to embed common fields.but it's can't init dateCreated and createdBy,what'd i do?extends domain or embedded is right way to handle common fields?
code to say?
class Created {
Date dateCreated
Long createdBy
def beforeInsert()
{
dateCreated= new Date()
createdBy=0
}
}
class Updated {
Date lastUpdated
Long updatedBy
//it works?
def beforeUpdate(){
lastUpdated=new Date()
updatedBy=0
}
//it works?
def beforeInsert(){
lastUpdated=new Date()
updatedBy=0
}
}
class CreatedUpdated {
Created created
Updated updated
//Must use the embedded option, or the type of exception, can not find CreatedUpdated
static embedded = ['created','updated']
}
class Term {
String name
CreatedUpdated createdUpdated
static embedded = ['createdUpdated']
Term parent
static hasMany =[terms:Term]
static mapping = {
version false
}
String toString()
{
name
}
static constraints = {
name unique:true,size: 1..20
parent nullable: true
createdUpdated display:false,nullable:true
terms display:false
url url: true
}
}
or use extends?
class Term extends CreatedUpdated{
String name
Term parent
static hasMany =[terms:Term]
static mapping = {
version false
}
String toString()
{
name
}
static constraints = {
name unique:true,size: 1..20
parent nullable: true
terms display:false
url url: true
}
}
`
what is right to me?
I'd definitely make this example embedded rather than inherited. I don't think you should make this call based solely on the fact that objects contain common fields. Instead, you should use inheritance if it makes sense for your model using standard OO design techniques. For example, if "myClass is a myBaseClass" doesn't hold true, inheritance is probably the wrong solution.
In general, I'd stay away from classes like CreatedUpdated that are just a collection of properties and not an actual object from your domain. Java/Groovy has only single inheritance, so this only works if you have one base class like this.
Also, for that particular case, created and updated timestamps can automatically be applied by GORM. If you're using spring security, check out the audit-trail plugin for automatically creating createdBy and updatedBy columns.
In this particular case audit-trail plugin should suffice the requirements. However if you have such requirement for other fields wherein no plugin is available, then one of the possible solution could be to inject such common fields at compile time via AST Transformation. Internally audit-trail plugin uses this concept to inject those fields. Depending upon your requirement you can either use Global AST Transformations or Local AST Transformations.

Default Values in LINQ Modelling

To put it in basic form, my database table doesn't allow nulls for varchars, it must have blanks. My model doesn't allow nulls so it won't insert a record if I leave form fields empty. If an empty form field appears I want a default value of blank to be used instead. I've tried, for example, the following without any luck:
[Column]
[DisplayName("WMD Company")]
[DefaultValue(" ")]
public string WMDCompany { get; set; }
So instead, in my controller action I have to do a check like the following:
if(myModel.WMDCompany == null) myModel.WMDCompany = " ";
Which is plain nasty to me. Is there any way of getting [DefaultValue(" ")] to work?
Cheers
What about something like this:
private string wmdCompany;
public string WMDCompany
{
get
{
if (this.wmdCompany == null)
{
return string.Empty;
}
return this.wmdCompany;
}
set
{
this.wmdCompany = value;
}
}
The DefaultValue attribute is not used. LINQ to SQL has not support for DB defaults unfortunately. That property is intended for use in API extension if I remember, but I don't know of any that use it.
Two approaches to get around this you could use.
First update your data layer, by appropriately controlling the property, and setting it to null. Use a partial class to extend your data class, and implement the OnCreated() partial method, and in this set the value to String.Empty.
partial void OnCreated()
{
MyProp = String.Empty;
}
Secondly, you could change your DBML representation to allow nulls, but in your database, use a trigger to convert NULLs to empty strings.
I'd go with the first approach myself - assuming you can't just use NULLs as suggested by Adrian
Inserting spaces as a placeholder for NULL seems like a very obscure method to me. Why don't you just change your table design to allow NULL values?

Resources