Criteria on a one-to-many relation - grails

My domain contains a one-to-many relationship like this:
class A {
B b
}
class B {
String name
}
I want to create a criteria query on A which will look for A to have the B object with the given name. It may return multiple entries. So... compare a given string with the "name" field from B and return the list of entries of type A for which B matches the name.
Thx!

Unless I am missing something that should be pretty easy:
def instanceList = A.withCriteria {
b {
eq('name','whatever')
}
}

Related

Deleting the object and its mapping in one-to-many in grails

I have 2 domain classes as follows -
class A {
static hasMany = [B] // Just trying to show my mapping
}
class B {
// This table doesn't belongs to A
}
Now I have a object of class A which contains a set of objects B. I want to delete object A and its association with B, but I don't want to delete object B.
I have tried cascade for delete, delete-all & delete-all-orphan but it seems to be trying to delete the associated records from table B which isn't what I want.
This is what I am doing right now -
objectTypeB.each { b ->
a.removeFromB(b)
}
and then
a.delete()
but getting error
deleted object would be re-saved by cascade (remove deleted object from associations)
Your example is almost correct, I think what you need is tell A what collection to store B's in (see the hasMany)
class A {
String name
static hasMany = [b: B]
}
class B {
String name
}
Then it should be possible to do this (I tried it in a blank project, where my domains also have a String name property):
def b1 = new B(name: 'b1').save(flush: true)
def b2 = new B(name: 'b2').save(flush: true)
def b3 = new B(name: 'b3').save(flush: true)
def a = new A(name: 'a')
a.addToB(b1)
a.addToB(b2)
a.save(flush: true)
def x = A.get(1)
println x.b
x.delete(flush: true)
assert A.count() == 0
Since there is no relation from B to A, there is no need to remove the b's from A before deleting the A. If you want, I can send you my code sniplet

Grails - get domain relationship id without fetching the whole object

I have, for example, the following domain objects:
class A {
B b
static constraints = {
b nullable: true
}
}
class B {
}
Given instance of A, I would like to fetch only the id of B.
I tried the following, but received null every time:
def id = a.bId
Is it possible to fetch the id of b without doing a.b.id ?
You will need to enhance your domain to use GORM based mapping hints (given to Hibernate) to accomplish this.
Your domain could look something like this:
class A {
static hasOne = [b: B]
}
class B {
// stuff
}
Using the hasOne will allow Hibernate to manage the association and thus allows you to use the a.bId notation.
Hope this helps.

Grails search owned objects by properties

I am trying to find the proper syntax for a query that I know has got to be very common but couldn't find a code example for.
class ObjA {
...
static hasMany = [b:ObjB]
}
if a is an instance of ObjA, I want to perform a query like:
a.b.findAllBsSuchThat(b.someproperty = somevalue)
In order to avoid (N+1) queries for lazy associations per a, you can use a criteria as:
ObjA.withCriteria {
b {
eq 'someProperty', someValue
}
}
or where queries:
ObjA.where { b.someProperty == somevalue }.list()
If you use something like a.b.findAllBsSuchThat(b.someproperty = somevalue) then you would be getting all b's for a and then filtering on the result. This will affect the performance and will unnecessary.

Grails searchable relationship

I am wondering how to return specific domain with searchable?
For example we have domain A and B. Both domain are searchable and have relationship: A has many B and B belongs to A. Another case A and B have many-to-many relationship.
Now when I search for item, I must always return A item. In my case let say I found matches in B, I need to return all As for each B. Other way around should work as well.
Currently I do a search query is searchable services:
def searchResults = searchableService.search(params.q, params)
Is there a way to get all related A domain for any search results?
Thank you.
Make both your domains(A & B) searchable and then add DomainObject component:true in searchable properties.
class A{
String name
static hasMany = [bclass: B]
static searchable = {
bclass component: true
}
}
class B{
String color
static belongsTo= [aclass: A]
static searchable = true
}
Suppose in B there are some rows with color field value as 'red'
A.search("red")
will return all the instances of A, which has its child class B with color field value as 'red'

Grails gorm query question

having the domain classes:
class A {
Date dateCreated
static hasMany = [b:B]
...
}
class B {
String name
String value
...
}
What createCriteria or HQL query can I use to return a list with:
A's creation dateB's value for A with the name entry set to 'X'
Note: Although there's no explicit constraint, there's only one "value" for each 'X' and a combination.
Thanks
The HQL would be
def results = A.executeQuery(
'select a.id, a.dateCreated, b from A a inner join a.b b ' +
'where b.name=:name',
[name: 'X'])
This will give you a List of 3-element Object[] arrays containing A.id, A.dateCreated, and the list of B instances. I added the id to the query so you can group by it client-side:
def grouped = results.groupBy { it[0] }
This will be a Map where the keys are the A ids and the values are the Lists from the original results.
Ideally you'd do the grouping at the database, but it would complicate the query, and assuming you don't have a large number of results it should be fast.

Resources