Grails named query - grails

I have two domain classes, Alpha and Beta.
class Beta{
String betaName
int age
}
class Alpha{
String name
static belongsTo=[creator:Beta]
static namedQueries = {
alphaByUser{ param ->
eq creator.betName,param.betaName
}
alphaByAge {param ->
eq creator.age,param
}
}
}
Now when I call for example Alpha.alphaByUser(betaUser).list() I keep getting things like:
java.lang.NoSuchMethodException: Unknown property 'create' on class 'class org.codehaus.groovy.grails.commons.DefaultGrailsDomainClass'
Or
object is not an instance of declaring class
I just can't seem to get past it...
Any suggestions?

Your criteria syntax is a bit off. Try this:
static namedQueries = {
alphaByUser{ param ->
creator {
eq 'betName', param.betaName
}
}
}

Related

Access object's properties inside named query

Is it possible to access an object's property inside a named query?
Here is a sample domain class
class Publication {
String title
String author
Date datePublished
Integer numberOfPages
static namedQueries = {
newerPublications {
//Will throw an error, cannot access a variable declared in a dynamic context.
gt 'datePublished', this.datePublished
}
}
}
You can do something like this:
newerPublications { Publication newerThan ->
gt 'datePublished', newerThan.datePublished
}
You would then call it as Publication.newerPublications(referencePublication).list()

grails 2.2.2 service don't know domain model: "No signature of method"

I have a grails-plugin called "listadmin" there is a domain model "Liste":
package listadmin
class Liste {
String internal_name
String public_name
Boolean edtiable = true
Boolean visible = true
static hasMany = [eintrage : ListenEintrag]
static constraints = {
internal_name(unique : true , blank : false);
}
String toString() {
"${public_name}"
}
}
I have service called "SECO_ListenService" in the same module (grails-plugin):
package listadmin
class SECO_ListenService {
def getEntriesOfList(String intnalListName) {
def aList = Liste.findByInternal_name(intnalListName)
return aList
}
}
Now I try to call this service from an other module (grails-plugin) called "institutionadmin". The SECO_ListenService should return a list of strings for an select of a domain model in the inistitutionadmin:
package institutionadmin
import listadmin.SECO_ListenService
class Einrichtung {
Long einrichtungs_type
Long type_of_conzept
int anzahl_gruppen
int anzahl_kinder_pro_Gruppe
String offnungszeiten
static hasMany = [rooms : Raum]
static constraints = {
def aList = []
def sECO_ListenService = new SECO_ListenService()
aList=sECO_ListenService.getEntriesOfList("einrichtung_type")
einrichtungs_type(inList: aList)
}
}
If I try to run this application with the both modules. I get the following error:
Caused by MissingMethodException: No signature of method:
listadmin.Liste.methodMissing() is applicable for argument types: ()
values: []
It seemed to be that the service class don't know the "Liste"-domain-model. But I don't know where the error is. I also tried to call other standard methods like "findAll" but without any success.
Has anybody an idea where my mistake could be?
To get a service in a static context you need to access the grailsApplication spring bean. This can be done thought Holders. Example:
class MyService {
List<String> getAvailable() {
return ['A','B','C']
}
}
class MyDomainClass {
String something
static constraints = {
something inList: getSomethingList()
}
static List<String> getSomethingList() {
def myService = Holders.grailsApplication.mainContext.getBean('myService')
return myService.getAvailable()
}
}

Enum in Grails Domain

I'm trying to use an enum in a Grails 2.1 domain class. I'm generating the controller and views via the grails generate-all <domain class> command, and when I access the view I get the error shown below. What am I missing here?
Error
Failed to convert property value of type java.lang.String to required type
com.domain.ActionEnum for property action; nested exception is
java.lang.IllegalStateException: Cannot convert value of type
[java.lang.String] to required type [com.domain.ActionEnum] for property action:
no matching editors or conversion strategy found
Enum (in /src/groovy)
package com.domain
enum ActionEnum {
PRE_REGISTER(0), PURCHASE(2)
private final int val
public ActionEnum(int val) {
this.val = val
}
int value() { return value }
}
Domain
package com.domain
class Stat {
ActionEnum action
static mapping = {
version false
}
}
View
<g:select name="action"
from="${com.domain.ActionEnum?.values()}"
keys="${com.domain.ActionEnum.values()*.name()}" required=""
value="${xyzInstance?.action?.name()}"/>
EDIT
Now getting error Property action must be a valid number after changing the following.
View
<g:select optionKey='id' name="action"
from="${com.domain.ActionEnum?.values()}"
required=""
value="${xyzInstance?.action}"/> // I tried simply putting a number here
Enum
package com.domain
enum ActionEnum {
PRE_REGISTER(0), PURCHASE(2)
final int id
public ActionEnum(int id) {
this.id = id
}
int value() { return value }
static ActionEnum byId(int id) {
values().find { it.id == id }
}
}
Domain
package com.domain.site
class Stat {
static belongsTo = Game;
Game game
Integer action
static mapping = {
version false
}
static constraints = {
action inList: ActionEnum.values()*.id
}
String toString() {
return "${action}"
}
}
Take a look here ...
Grails Enum Mapping
Grails GORM & Enums
Also you may be hitting this as well. From the docs:
1) Enum types are now mapped using their String value rather than the ordinal value. You can revert to the old behavior by changing your mapping as follows:
static mapping = {
someEnum enumType:"ordinal"
}

Transient property in Grails domain

I have a Grails domain called People, and I want to check that each People has childs or not. Childs are other People objects. Here is my domain structure:
class People implements Serializable {
static constraints = {
name (nullable : false, unique : true)
createdBy (nullable : false)
creationDate (nullable : false)
}
static transients = ['hasChild']
static mapping = {
table 'PEOPLE'
id generator: 'sequence', params : [sequence : 'SEQ_PK_ID']
columns {
id column : 'APEOPLE_ID'
parentPeople column : 'PARENT_PEOPLE_ID'
}
parentPeople lazy : false
}
People parentPeople
String name
String description
Boolean hasChild() {
def childPeoples = People.createCriteria().count {
eq ('parentPeople', People)
}
return (childPeoples > 0)
}
}
But I cannot call people.hasChild() at anywhere. Could you please helpe me on this? Thank you so much!
It's because in eq ('parentPeople', People), Grails can't understand what "People" is (it's a class). You should replace "People" by this. For example:
static transients = ["children"]
def getChildren() {
def childPeoples = People.findAllByParentPeople(this, [sort:'id',order:'asc'])
}
Another way to get the same result is to use Named Queries. It seems more concise and was created specifically for this purpose. I also like it because it fits the pattern of static declarations in a domain model and it's essentially a criteria, which I use throughout my applications. Declaring a transient then writing a closure seems a bit of a work-around when you can declare named queries ... just my opinion.
Try something like this:
static namedQueries = {
getChildren {
projections {
count "parentPeople"
}
}
}

Grails: use domain method in named query

in my domain model, I have a method that does something with my data.
e.g.
class Person {
String lastname
String firstname
String bigname() {
return lastname.toUpperCase()
}
static namedQueries = {
withBigname { name ->
eq(this.bigname(), name)
}
}
}
I want to use this method like a property in the named query, but this.bigname() only throws a java.lang.IncompatibleClassChangeError-Exception.
Does anyone know how to use domain methods in criteria and named queries?
Update: I now tried this:
class Person {
String lastname
String firstname
String bigname
static transients = [ 'bigname' ]
def getBigname() {
return lastname.toUpperCase()
}
static namedQueries = {
withBigname { name ->
eq('bigname', name)
}
}
}
But it only results in a "could not resolve property: bigname"-exception...
You cannot use class methods in queries, because queries are actually translated to SQL.
You might be able to get what you need by using writing the complexity in SQL a "SQL Restriction". Search for "SQL Restriction" on http://grails.org/doc/2.0.x/guide/GORM.html
HTH
Try to name the method in JavaBean getter and setter notation.
Rename method bigname() to getBigname().
On a static closure, you don't have a this. You'll either need to store the bigname in the Database, do some sort of case insensitive criteria.
looks like you are trying to accomplish this:
class Person {
String lastname
String firstname
static namedQueries = {
withName { name ->
eq('lastname', name, [ignoreCase: true])
}
}
}

Resources