HQL order by max item in child list - grails

I have the following domain classes
class Child{
def age
}
class Parent{
static hasMany = [children:Child]
}
and I would like to execute the following in HQL
Parent.list()
.sort{ parent -> parent.children.sort{ child -> child.age}[0]}[0..10]
Basically I would like to retrieve a list of parents sorted by the age of their eldest child. And restrict this to only 10 records. I don't want to pull all parent and child records from the database, and then do the necessary sorting. I was hoping that HQL could do this on the 'database layer', and only return the results I need. Thanks :)

Parent.withCriteria {
createAlias('children', 'ch', org.hibernate.criterion.CriteriaSpecification.LEFT_JOIN)
order("ch.age", "desc")
maxResults(10)
setResultTransformer(org.hibernate.criterion.CriteriaSpecification.DISTINCT_ROOT_ENTITY)
}

Related

Grails distinct projection get the result count of distinct items

I am using grails-2.5.6 version. I am using spring-security-core plugin. I have a criteria query on UserRole table. Where I want to find all distinct users by a role. It is working properly.
But the problem is the pagination effect. When I am counting on the list it is counting on UserRole list object. But I need the count on distinct projection items. Here is my attempt below:
def list(Integer max) {
def userInstanceList = UserRole.createCriteria().list(params) {
createAlias('user', 'au')
createAlias('role', 'ar')
projections {
distinct("user")
}
if (params.roleId) {
eq('ar.id', params.getLong("roleId"))
}
}
def totalCount = userInstanceList.totalCount
[userInstanceList: userInstanceList, totalCount: totalCount]
}
Here, totalCount is the number of UserRole list. But I want the distinct projection count.
I would tackle this slightly differently, you want to analyse the users, not the userroles.
So I'd do something like:
List<User> usersWithRole = UserRole.createCriteria().list(params) {
role {
eq('id', params.getLong("roleId"))
}
}*.user
int count = usersWithRole.size()
Unless of course there's hundreds or thousands of users, in which case I wouldn't want to load all of them each time and would revert to SQL.
Is this a custom version of spring security you're using? I've never seen Roles with a 'long' based ID, usually, the key is a String representing the Authority name.
Usually the DBAs see the use of distinct keyword as a code-smell.
In your case I would rather use the User as the main domain object to run the query against and a group by clause:
long id = params.getLong "roleId"
def list = User.createCriteria().list( params ) {
projections{
groupProperty 'userRole.role.id'
}
if( id )
userRole{
role{
eq 'id', id
}
}
}

Grails : Retrieve all latest children records

I am new to Grails , I have some issue as stated below.
I have 2 domain classes : Parent and Child. I am storing arrays of arrays into database.
Parent class is :
class Parent{
static hasMany = [child: Child]
}
Child class is :
class Child {
String time
String record
String value
static belongsTo= [parent: Parent]
static constraints = {
time(blank: false)
record(blank: false)
belongsTo(blank: false)
}
}
Now my requirement is :
I need to retrieve the child's latest records that contain multiple rows in the database with unique parent id.
e.g : Parent's latest id is 7.
Child table contains nearly 10 records on parent id 7. I want to retrieve all these 10 records with the reference of the parent id(7).
Please some one help to write a code/query .
gorm is a greate ORM you could use following:
def parent = Parent.get(7)
def childList = Child.findAllByParent(parent);
read this, it'll help you to understand gorm better.

Grails 1:m get most relations

I'm relatively new to Grails.
I have the following
class House {
Integer number
Integer maxResidents
static belongsTo = [town: Town]
}
class Town {
String name
static hasMany = [houses: House]
}
I want to get five towns with most Houses. I have seen the possibility to create a criteria but I can't deal with it now. Can someone support?
Thank you!
As you have a bidirectional association you can do this with a query on House:
def result = House.withCriteria {
projections {
groupProperty("town", "town")
rowCount("numHouses")
}
order("numHouses", "desc")
maxResults(5)
}
This would return you a list of results where each result res has the town as res[0] and the number of houses as res[1]. If you'd prefer each result to be a map giving access to res.town and res.numHouses then you should add
resultTransformer(AliasToEntityMapResultTransformer.INSTANCE)
after the maxResults line (along with the appropriate import at the top of your file).

Sort based on column in child table using GORM?

I have a table called employee and child table address.
Now I want to get a list of employees sort by address1 in address table using GORM.
Employee.findAllByName(name, [max: maxRecords, offset: 100,sort: Address.address1, order: desc])
the above statement is not working, any suggestions would be appreciated.
Thanks
Try using a criteria query like so...
def c = Employee.createCriteria()
def results = c.list (max: maxRecords, offset: 100) {
eq("name", name)
address {
order("addres1", "desc")
}
}
This works for me!
Another option is to add a default sort order like so...
class Address{
…
static mapping = {
sort address1:"desc"
}
}
However, I always prefer to do things as an 'as-needed' basis rather than define that sorting be done every time even when it may not be needed. U pick. Enjoy!

Grails GORM Domain class relationship

Grails 1.1.1
Goovy 1.5.7
In a relationship such this:
Author 1 -- n Book n -- 1 Publisher
Defined in Grails:
class Author {
String firstName
String lastName
static hasMany = [books: Book]
static constraints = {
books(nullable: true)
}
}
class Book {
String title
Author author
Publisher publisher
static constraints = {
author(nullable: true)
publisher(nullable: true)
}
}
class Publisher {
String name
static hasMany = [books: Book]
static constraints = {
books(nullable: true)
}
}
I want to load a Book with the values of Publisher and Author.
When i get a Book with the query:
def book2 = Book.findAllByAuthor(author)
I get the response with the autor assosiated but the publisher only have the id and name class in the other query:
def book3 = Book.findAllByPublisher(publisher)
I retrieve me the inverse result,i have the book with the publisher data but the author only have the id and the class name.
Where is the error in the defined model ? o there is an error in the way to do the queries ?
Edit:
I need the way to retrieve the values only with the query like this:
def book2 = Book.findAllByAuthor(author, [fetch:[publisher:'eager']])
In this one I can manage the value of publisher.
Question: If publisher had a hasmany or Domain related, getting the book I'm able to read the attributes?
Thanks.
Thanks.
Lazy fetching is used by default with gorm associations. If you want to enable eager fetching, you can modify the ORM DSL by adding the following mappings block to your Author domain class:
static mapping = {
books lazy:false
}
or you could change the fetch mode in the domain object by adding following code after your books relationship is defined.
static fetchMode = [books:"eager"]
Doing the same to your Publisher domain object should allow you to accomplish what you want. You do want to be careful of the consequence that you may load more data than you intend to.
Shouldn't the get() method return what you are looking for?
Example: def book2 = Book.get(author)
You'd better use Criteria and explicitly define which relations should be loaded eagerly. Just mention relation in the query.
Example:
def c = Teacher.createCriteria()
List<Teacher> results = c.list {
subjects {
attendees {}
}
}

Resources