GORM/grails deep distinct association query criteria - grails

I have domain objects for each table specified in the below query. I'm having trouble creating the withCriteria closure representing the below SQL query. Any thoughts?
Thanks!
Steve
SQL Query:
select A_NAME from A
where A_XID =
(select A_XID from B
where B_XID =
(select distinct B_XID from C
where D_XID = '${d.dXid}')
Domain Objects:
class A {
String aName
BigDecimal aXid <-- unique identifier
}
class B {
A a
BigDecimal bXid <-- unique identifier
}
class C {
D d
B b
}

I'm not sure how to do this with a criteria query, but in HQL it'd be
String aName = A.executeQuery(
'select c.b.a.aName from C c where c.d = :d',
[d: d])[0]
but you've left out a lot of information, so this is based on the assumption that you have these domain classes (you omitted the D class and mappings):
class A {
String aName
BigDecimal aXid
}
class B {
A a
BigDecimal bXid
static mapping = {
a column: 'A_XID'
}
}
class C {
D d
B b
static mapping = {
b column: 'B_XID'
d column: 'D_XID'
}
}
class D {
String someProperty
}

Related

How to query 3 tables in Grails Gorm

I am new to grails framework how to query 3 tables having association between them
Class A{
static hasMany = [b:B]
}
enter code here
class B{
long aId // Id of table A
}
class c{
B b //B reference
}
SQL query: select * from C where b_id in (select id from B where a_id='10'_)
Any help will be appreciated.
Straight-forward
def list = C.withCriteria{
b{
eq 'aId', '10'
}
}

How can I get dateCreated in Has-Many Relation in Grails?

I have the following domain classes:
class A {
hasMany = [bs : B]
}
class B { }
Note that B has no backward relation to a. GORM creates a join table in my MYSQL database a_b. This table has two columns the id of a and the id of b.
How can I get a dateCreatedin the join table?
Create a model of the join table yourself and add whatever properties you want on it. Simple, and done.
For example:
class A {
static hasMany = [bs: JoinB]
}
class JoinB {
static belongsTo = [a: A]
B b
Date dateCreated
static mapping = {
autoTimestamp true // default, but I like to be explicit about it.
}
}
class B {
String whatever
}
(Careful of typos etc. I just did that off the top of my head)

Fast way to get to perform a request from multiple hasMany association

What is the fast and best way to perform a request from multiple 'hasMany' association ?
Here's a simple code that I have.
From the instance of A I want to get all instances of B domain (a list of id) where login == "toto"?
class A {
static hasMany = [BList:B]
}
class B {
static hasMany = [CList:C]
}
class C {
static hasMany = [DList:D]
}
class D {
String login
}
Thanks
You can do it with an HQL:
String query = """
from a.bList
where a = :a
and exists (select 1
from C c
, D d
where d.c = c
and c.b in a.bList
and d.login = :login)
"""
def result = A.executeQuery(query, [a: aInstance, login: "login"])
More information about executeQuery in the docs.

Grails: Children of Children

I have a question about GORM and "multiple" hasmany relationships, and I didn't find an answer in my previous searches.
Let's say we have three domains:
class A {
...
static hasMany = [Bs: B]
}
and
class B {
...
static belongsTo = A
static hasMany = [Cs: C]
}
and
class C {
static belongsTo = B
String name
dateCreated date
}
I want to know if it is possible to get a list of objects of the class C, sorted by dateCreated, using an object of the class A (something like C.findAll(...., a: a.id) ) or if I have to use a more complex query ?
Best regards,
Its a little more difficult because you aren't storing a back reference to the parent objects
Something like this - I didn't test it myself
A.executeQuery("select distinct c from A a join a.bs as b join b.cs as c where a = :a", [a: a])
If B has:
static belongsTo = [a:A]
then you can do:
C.withCriteria {
a{
eq('id', <a's id here>)
}
order('dateCreated', 'desc')
}

How to implement a count in a subquery

I have the following table structures:
TABLE A:
ID
COL1
COL2
...
COL(n)
TABLE B:
ID
A_ID (id in table A)
VALUE
There is a one-to-many relationship from A->B
class A {
int id
...
coln
Set<String> bSet
static hasMany = [bSet: B]
static mapping = {
restrictions joinTable: [name: "B", key: "A_ID", column: "VALUE"]
}
}
How can I build a criteria so that it executes a query such as follows:
select table1.* from A table1 where (select count(*) from B table2 where table2.A_ID = table1.ID and table2.VALUE in ('excluded_value_1','excluded_value_2')) = 0
Give this a try, obviously untested but might give you something to start from
def a = A.createCriteria()
a.list {
createAlias("bSet", "b", CriteriaSpecification.LEFT_JOIN)
not {
'in'("b",['excluded_value_1','excluded_value_2'])
}
}

Resources