HQL Join in Grails - grails

I am trying to execute a query to gather specific data but encountering problems in the query on the on portion of the query. To start off this is my class:
class TimeSlot {
String timeslot_id
String time_chunk_id
String uid
String exam_id
String start_time
String is_special_arrangement
static mapping = {
table 'timeslot'
id name: "timeslot_id", column: "timeslot_id"
version false
}
}
This is the query I'm trying to get working:
TimeSlot.executeQuery("Select t.time_chunk_id, t.uid, t.start_time, t.timeslot_id, t.is_special_arrangement, e.length from TimeSlot t inner join Exams e on t.exam_id = e.exam_id where t.exam_id = ? and t.time_chunk_id = ?", [testArray[i], timeChunkArray[x]])
It's throwing an error on the on portion because it's expecting a clause, but I need the data to specifically pertain to the exam.id comparison of both tables. Is there another way around this or a different way to set up the query so it will work like it does in any SQL editor?

It would be easier if you alter the domain class and add one to many relationship
class TimeSlot {
static hasMany = [examinations:Exams]
Then HQL can be
select ... from TimeSlot t join t.examinations e

Related

How can I get graphql-ruby to use joins when accessing subfields?

I have a model like this
class Foo
has_many :bars
end
and a query like this
query foos(
$offset: Int
$sort_by: String
$should_paginate: Boolean
) {
foos(
offset: $offset
sort_by: $sort_by
should_paginate: $should_paginate
) {
id
name
bars {
When I fetch this query, I get one select * from "foos" for each bar that's in the collection.
How can I have this all be smarter and do fewer SQL queries?
Look at https://github.com/Shopify/graphql-batch
It uses allows you to lazy-load your associations at once on demand.

Grails joining tables

I have two classes. For simplicity, I removed unrelated data. I need join Order to Survey not vice-versa.
I know that I can run
select * from Order o right join order.survey s where s.id='x'
However, it is not what I would like to do. I would like to join Order to Survey with left outer join, but the survey doesn't have an instance of Order class in the class. The order holds an instance of the survey class, that's why it is easier to join tables from order class. I did it using SQL in Grails, however I wonder how it can be done using hql.
The sql code is as following.
Select survey.*,ao.* from survey sr left outer join order ao on ao.survey_id=sr.id
Models are as following
class Order{
Survey survey
}
class Survey {
}
Try this:
SELECT sr, (SELECT ao FROM namespace.Order ao WHERE ao.survey = sr.id)
FROM namespace.Survey sr
You list all Survey objects and if exists an associated Order you'll get by subquery
Pay attention: I've add namespace term, you'll change with your namespace class
In order to do joins in HQL, you have to extend your domain model. Add a back-ref to your Survey class:
class Survey {
static belongsTo = [ order:Order ]
}
so, you can resolve the Order instance from it:
Survey s = Survey.get someId
s.order
or
def orders = Survey.executeQuery 'select order from Survey where order.id = 111'

A oneToMany join in Grails using findAll or HQL

I'm new to Groovy and HQL querying but I can't find a solution to this anywhere so it's driving me nuts.
I have two Domain classes which have a one to many relationship defined (a user can have many companies) and I effectively need to do (what would traditionally be called) 'a table join' but clearly with objects.
The classes go like this:
class User {
transient springSecurityService
static hasMany = [company: Company]
String username
String password
boolean enabled
boolean accountExpired
boolean accountLocked
boolean passwordExpired
...
...
...
}
... and the company class
class Company {
static scaffolding = true
String name
String address1
String address2
String address3
String address4
String postCode
String telephone
String mobile // mobile number to receive appointment text messages to
String email // email address to receive appointment emails to
static hasMany = [staff: Staff]
static belongsTo = [user: User]
...
...
...
}
Gorm has created an user_id field within the company table but any attempt to use this in a query returns an error.
So how would I do something like:
select * from user u, company c, where u.id = c.user_id;
What is the best way to do this?
You can effectively use join on the association something like:
HQL
select * from User as u inner join fetch u.company as companies where u.id = ?
Note that using fetch in the query would eagerly fetch the associated collections of companies for a user
findAll()
User.findAll("from User as u inner join fetch u.company as companies where u.id = ?", [1])
Benefit of using findAll instead of HQL is that you can easily implement pagination something like:
User.findAll("from User as u inner join fetch u.company as companies where u.accountExpired = true", [max: 10, offset: 5])
To get a concrete implementation and really understand things in details I would insist to have a look at findAll and HQL associations.

Select of hasMany mapping with GORM in Grails

Suppose I have a setup like the following:
class User {
static hasMany = [items : Item];
}
class Item {
String name;
}
I'm trying to select all Users that have an Item in that hasMany mapping. I have an id of an Item, and want to find all users that “have” that item.
Is there a HQL query I can run that will do this or better yet, a built in GORM function that handles this query?
Supposing this were straight SQL I would do something like:
SELECT `user_id` FROM `user_item` WHERE `item_id`=[ID]
Looking in H2 I can write the query
SELECT USER_ID FROM USER_ITEM WHERE ITEM_ID=1;
I can expand this SQL to include the entire user object:
SELECT * FROM user, user_item WHERE user_item.item_id=[item id] AND user.id = user_user.user_items_id;
This HQL will work:
Item item = ...
Item.executeQuery(
'from User u where :item in elements(u.items)',
[item: item])

How to search an inner class?

I have these classes.
class Author{
Person person
}
class Person{
String lastName
String firstName
String middleName
}
I'd like to query Person and Author.
def persons = Person.findAllByLastNameiLike("${a}")
but it seems I can't do
def authors = Author.findAllByPerson(persons)
Any ideas how I'd do this?
This code shown above does not work
def authors = Author.findAllByPerson(persons)
because findAllBy* works with a single object, not a collection. To find all authors where the Person is any one of those contained in persons use either HQL or a criteria query. For example an (untested) HQL query would look something like:
Author.executeQuery("""
FROM Author a
WHERE a.person IN (:people)""", [people: persons])

Resources