Given
class Store {
String name
static hasMany = [departments: Department]
}
class Department {
String name
static belongsTo = [store: Store]
static hasMany = [products: Product]
}
class Product {
String name
Integer qty
static namedQueries = {
productsInStockByStore {store->
department {
store {
eq 'id', store.id
}
}
gt 'qty', 0
}
}
static belongsTo = [department: Department]
}
I get an error running:
def store = Store.first() // just for the sake of testing
Product.productsInStockByStore(store).list()
No signature of method: namedboom.Store.call() is applicable for
argument types:
(namedboom.Product$__clinit__closure1$_closure3$_closure4$_closure5)
values:
[namedboom.Product$__clinit__closure1$_closure3$_closure4$_closure5#768aab6a]
Possible solutions: wait(), last(), save(), any(), getAll(),
wait(long)
What would be the right way to accomplish this with named query? The only way I could get it to work is using createCriteria and declaring joints for the parent tables.
This is may be because store is defined in your named query. Try changing name of this variable in the named query, like
static namedQueries = {
productsInStockByStore {storeInstance->
department {
store {
eq 'id', storeInstance.id
}
}
gt 'qty', 0
}
}
Related
I have this class:
class Word {
String word
static hasMany = [group: WordGroup]
static belongsTo = [language: Language]
static constraints = {
word(unique: ['language'], maxSize:255)
}
}
Which is working fine, but I would need to associate the unique constraint to both language and group, so different groups can insert the same "word".
The groups are in an intermediate table (WordGroup) as this is a many to many relationship.
If I try to do
word(unique: ['language', 'group'], maxSize:255)
I get the error
Missing IN or OUT parameter in index:: 3
Is there a way to do this?
EDIT: I am adding the other classes referenced in the Word class if it helps
WordGroup
class WordGroup {
static belongsTo = [word: Word, group: Group]
static constraints = {}
}
Group
class Group {
String name
String url
static hasMany = [words: Word]
static constraints = {
name blank: false, unique: true
}
}
Language
class Language {
String name
String code
static constraints = {
name maxSize:255
code maxSize:255
}
}
Thanks.
when I use the bellow code see the exception Found two representations of same collection.
how can fix this problem?
class ProductModel implements Serializable{
static auditable = true
String name
Product product
Guarantee guarantee
String status
Integer width
Integer height
Integer weight
static hasMany = [variationValues: VariationValue, prices: Price]
static composites = ["prices"]
static mapping = {
sort 'id'
prices cascade: "all-delete-orphan"
searchKeys type: 'text'
}
in ProductModelController I have this code for delete()
def delete() {
def pricemodel = Price.findAllByProductModel(productModelInstance).findAll()
pricemodel.each { price ->
productModelInstance.removeFromPrices(price)
}
productModelInstance.save()
pricemodel.each {
it.delete()
}
productModelInstance.delete(flush: true)
In Grails I have these 4 domain classes:
package com.whatever.ts4
class A_class {
String aName
static hasMany = [b_class: B_class]
}
package com.whatever.ts4
class B_class {
String bName
A_class a_class
static hasMany = [c_class: C_class]
static belongsTo = [A_class]
}
package com.whatever.ts4
class C_class {
String cName
B_class b_class
static hasMany = [d_class: D_class]
static belongsTo = [B_class]
}
package com.whatever.ts4
class D_class {
Long rowNumber
String dataValue
C_class c_class
static belongsTo = [C_class]
}
Simple ER diagram:
A_class 1=>many B_class 1=>many C_class 1=>many D_class
I'm successfully populating them in BootStrap.groovy
Now,given an single A_class id, I need to obtain a set with these columns:
aName, bName, cName, rowNumber, dataValue
Can I do that using namedQueries?
I’ve tried putting this in the A_class domain class:
static namedQueries = {
myNamedQuery { aid ->
createAlias b_class,'b'
createAlias 'b.c_class','c'
createAlias 'c.d_class','d'
eq 'id',aid
}
}
I like the idea of a named query, because this result set will need to be returned for different A_class id’s. I can utilize a Service to prep the data and call it via the Controller which will render it as JSON (I digress). But, perhaps there is a Groovier way?
You don't need named query for this kind of action. You will obtain all information that you need just by taking it from A_class entity. For example:
def a_class_entity = A_class.get(id)
def b_names = a_class_entity.b_class.bName // set of all bNames
//<-- Not sure if flatten() works with spread collection fields, but it should -->
def c_names = a_class_entity.b_class.c_class.flatten().cName // collection of all cNames
def rowNumbers = a_class_entity.b_class.c_class.d_class.flatten().rowNumber // collection of all rowNumbers
def dataValues = a_class_entity.b_class.c_class.d_class.flatten().dataValue // collection of all dataValues
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"
}
}
}
I have a problem getting sorting to work with multiple joined tables. For example:
class Account {
static hasMany = [subscriptions: Subscription]
static mapping = {
subscriptions fetch: 'join'
subscriptions sort: 'magazine'
}
}
class Subscription {
static belongsTo = [account:Account, magazine: Magazine]
static maping = {
magazine fetch: 'join'
magazine sort: 'name'
}
}
class Magazine {
String name
static mapping = {
sort name: 'desc'
}
}
When someAccount.subscriptions is called generated query orders by magazine.id. Is there any way to get order by magazine.name? I tried changing to subscriptions sort: 'magazine.name' but get an error there is no such property.
Following: http://grails.org/doc/latest/guide/single.html#5.5.3 Default Sort Order I tried to move sort to association level by removing sort from Account and keeping sort in Subscription only but that ended up removing "order by" from resulting query completely. Any ideas? Thanks.
Try implementing a compareTo method in your Magazine class:
class Magazine implements Comparable {
String name
int compareTo(obj) {
name.compareTo(obj.name)
}
}
Then one in Subscription
class Subscription implements Comparable {
static belongsTo = [account:Account, magazine:Magazine]
static constraints = {
}
int compareTo(obj) {
return magazine.compareTo(obj.magazine)
}
}
Then make the subscriptions a SortedSet in Account:
class Account {
SortedSet subscriptions
static hasMany = [subscriptions:Subscription]
}