I have a small grails service that I created, and I am trying to use the type:'text' on a member of a model. I always see this field come up as a varchar(255) however, even though I have dropped the database and had it recreated.
I essentially have:
class eventParameter{
static belongsTo = [logEvent:LogEvent]
String name
String value
static constraints = {
name blank:false
value blank:false
}
static mapping = {
value type:'text'
}
}
Does anyone have any idea why this does not create the right type of column?
To override the underlying database type, use the sqlType mapping. For example:
static mapping = {
value sqlType:'text'
}
Also, check out the relevant section of the Grails Manual: 5.5.2.10 Custom Hibernate Types
Related
Using the map automatic creation on domain classes doesn't fill in transient properties:
class Address {
String street
String number
static transients = ["number"]
}
def address = new Address(street: "King's Street", number: "23")
println address.street //King's Street
println address.number //null
Is there any good reason for that? Grails domain instantiation overrides the default Groovy behaviour?
You can do it by two-way.
If you want to make transient a field, you need to bind it.
class Address {
String street
String number
static constraints = {
number bindable: true, nullable:true
}
static transients = ['number']
}
You can bind it using some getter method.
class Address {
String street
String number
String getDifferentNumber() { number }
static transients = ['differentNumber']
}
Hope it will help you. Enjoy.
Is there any good reason for that?
Yes. This has been the behavior since Grails 2.0.2. Properties which are not bindable by default are those related to transient fields, dynamically typed properties and static properties. There is some discussion about this at https://spring.io/blog/2012/03/28/secure-data-binding-with-grails.
Grails domain instantiation overrides the default Groovy behaviour?
Yes. This allows for doing a number of things which are common in a web app, like binding request parameters to a domain instance in a way that allows for a lot of flexibility needed to bind a bunch of Strings (request parameters) to a graph of objects.
If you really want to bind to a transient property all you have to do is configure the property to be bindable:
class Address {
String street
String number
static transients = ["number"]
static constraints = {
number bindable: true
}
}
See http://grails.github.io/grails-doc/2.4.5/ref/Constraints/bindable.html.
I hope that helps.
I'm new to Grails. I'm developing a web app that handles the records of a gymnasium, to make routines, exercises, etc.
I have this domain class Ejercicios:
class Ejercicios {
String nombreEjercicio
String idHoja
String descripcion
List<String> descripcionO
static hasMany = [descripcionO: Descripciones]
static transients = ['descripcionTrans']
String descripcionTrans
static mapping = {
id column: "idHoja"
version false
}
static constraints = {
nombreEjercicio maxSize: 45
idHoja blank: false
}
The database table has the default Grails id named "idHoja", and another attribute named "id_hoja"
The thing here is that when I make a JSON parse from the rest API, I need GORM to look for exercises via the "id_hoja" attribute, not the "idHoja" because it'll cause a mismatch.
I found the solution by myself!
The only thing I needed to was to make the JSON call with the name "idHoja" and that was it.
I'm creating a (theoretically) simple hasMany relationship within a domain class. I have two tables with a foreign key relationship between the two. Table 1's domain object is as follows:
Functionality{
String id
static hasMany = [functionalityControllers:FunctionalityController]
static mapping =
{
table 'schema.functionality'
id column:'FUNCTIONALITY_NAME', type:'string', generator:'assigned'
version false
}
}
and domain object 2
FunctionalityController
{
String id
String functionalityName
String controllerName
static mapping =
{
table 'schema.functionality_controller'
id column:'id', type:'string', generator:'assigned'
version:false
}
}
The issue I am having is that when I have the hasMany line inside of the Functionality domain object, the app won't start (both the app and the integration tests). The error is org.springframework.beans.factory.BeanCreationException leading to Invocation of init method failed; nested exception is java.lang.NullPointerException.
Any help would be appreciated.
UPDATE:
*Working Domains*:
class Functionality {
String id
static hasMany = [functionalityConts:FunctionalityCont]
static mapping =
{
table 'schema.functionality'
id column:'FUNCTIONALITY_NAME', type: 'string', generator: 'assigned'
functionalityConts( column:'functionality_name')
version false;
}
}
and
class FunctionalityCont {
String id
String functionalityName
String controllerName
static belongsTo = [functionality: Functionality]
static contraints = {
}
static mapping =
{
table 'schema.functionality_controller'
id column:'id', type: 'string', generator: 'assigned'
functionality(column:'FUNCTIONALITY_NAME')
version false;
}
}
Well 2 things...
1.I'm not sure but I guess that your domain class with the prefix 'Controller' maybe is the responsible, this is because grails is convention over configuration and by convention the controller class ends with Controller prefix and are in the controller folder, in this case is a lil' confusing
2.In GORM and in this case the relationship between objects can be unidirectional or bidirectional, is your decision to choose one, but in both cases there are different implementations, the class Functionality(btw is missing the 'class' word) has the right relationship to FunctionalityController through hasMany, but FunctionalityController doesn't knows about the relationship, so you can implement:
// For unidirectional
static belongsTo = Functionality
// For bidirectional
static belongsTo = [functionality:Functionality]
// Or put an instance of Functionality in your domain class,
// not common, and you manage the relationship
Functionality functionality
So check it out and tell us pls...
Regards
Try adding
static belongsTo = [functionality: Functionality]
to your FunctionalityController class. I suspect there is more to your error than what you've shown, but generally a hasMany needs an owning side to it. Since that is where the foreign key actually lives.
Hi I am trying to create a domain class with foreign key constraint to another existing domain class
New domain class is ArEntitlement defined as below
package ars
import gra.Resources
class ArEntitlement {
long id
String entitlementname
String entitlementdesc
String entitlementcomm
Integer departmentid
Resources resource
Integer version
static belongsto =[resource : Resources]
static mapping={
table 'ar_entitlement'
id(generator:'increment')
column{
id(column:'id')
}
}
}
Resource domain class is defined as follows (it was created before)
package gra
import com.gra.transaction.UserTransaction
class Resources {
Long id=1
String resourceName
Double resourceType
String resourceOwner
Double riskScore
Integer decommissioned
String resourceClass
Long resourceSegment
String targetIp
String resCriticality
Long resourceGroup
Integer disabled
static hasMany=[userTransactions:UserTransaction]
static mapping = {
table 'resource'
version false
id(generator:'increment')
column{
id(column:'id') }
}
static constraints=
{
resourceName(nullable:true,blank:false)
resourceType(nullable:true,blank:false)
resourceOwner(nullable:true,blank:false)
riskScore(nullable:false,blank:false)
decommissioned(nullable:false,blank:false)
resourceClass(nullable:false,blank:false)
resourceSegment(nullable:false,blank:false)
targetIp(nullable:false,blank:false)
resCriticality(nullable:true,blank:false)
resourceGroup(nullable:false,blank:false)
disabled(nullable:false,blank:false)
}
}
The resulting tables created dont have a foreign key mapping of ar_entitlement table to resource table, it does create a column called 'resource_id' but without foreign key constraint.
I need it to be pointing to id column of resource table
I tried several options, not having the belongsto specifier, using hasOne (in both domain classes) but not getting required foreign key relationship.
Any Idea what the issue is here?
log error i get is
2011-12-21 19:50:17,258 [main] ERROR hbm2ddl.SchemaUpdate - Unsuccessful: alter table ar_entitlement add index FKDCD6161FEFD54E5E (resourceid_id), add constraint FKDCD6161FEFD54E5E foreign key (resourceid_id) references resource (id)
Remove 'Resources resource' row from ArEntitlement.
static belongsTo = [resource : Resources]
Should cover that and having it defined twice might be the issue. Also you shouldn't need to specify the table names, the id generator or id column as it appears you are using the GORM defaults. Try removing these as well.
Here is the modified code...
package ars
import gra.Resources
class ArEntitlement {
String entitlementname
String entitlementdesc
String entitlementcomm
Integer departmentid
Integer version
static belongsTo = [resource : Resources]
static mapping = {
}
}
I've got a grails domain class I have to persist in Redis, something like this:
class A {
String one
Integer two
B three
E four
mapWith = "redis"
}
class B {
String name
}
enum E {
VALUE1, VALUE2
}
When I persist an instance of class A with the GORM .save() method, Redis saves it correctly except for the enum field "four".
As you can see the fact is known and reported here: http://jira.grails.org/browse/GPREDIS-3
Is there a good workaround to save Enum or something similar?
We're thinking about an array of String objects, what do you think?
I've got this mostly implemented but it doesn't work for Gemfire and I'm waiting until it's fixed for all the supported nosql providers before pushing the fix. As a workaround you can use the inList constraint with a combination of a persistent String property and a non-persistent get/set pair with the name of your current property, e.g.
class A {
String one
Integer two
B three
String fourString
void setFour(E e) {
fourString = e?.name()
}
E getFour() {
fourString ? E.valueOf(fourString) : null
}
static constraints = {
fourString inList: E.values()*.name()
}
static transients = ['fourString']
static mapWith = "redis"
}