Grails criteria select when hasMany hasn't any elements - grails

I have the classes:
class Course{
String name
static hasMany = [
studentGrades: StudentGrade
]
}
class StudentGrade{
String name
int grade
}
How can I make a criteria to get the courses without any student grade?

You could use the isEmpty criterion method:
def c = Course.createCriteria()
def results = c.list {
isEmpty("studentGrades")
}
See the docs for further informations.

Related

grails grom create criteria with many-to-many mapping

I have two domain classes: User and Book.
class Book implements Serializable{
String bookName
Timestamp createdDateTime
Blob file
static belongsTo = [User]
static hasMany = [user :User]
}
I am able to add user in book using addToUser() method.
But I am stuck in create criteria while applying filter in user.
def query = Book.createCriteria();
def results = query.list () {
eq("user",userObject) // not working since user field is a list of users.
order("createdDateTime", "desc")
}
Please help me with the correct way of filtering.
You need to join the user table first in a many-to-many relation. The criteria should look like:
Book.withCriteria {
user {
eq("id", userObject.id)
}
order("createdDateTime", "desc")
}
I'm not 100% sure how you're trying to model your domain but maybe you want a Book to have a single user? In which case you'd have the belongsTo relationship on Book e.g.
class Book {
String bookName
Timestamp createdDateTime
Blob file
static belongsTo = [user: User]
}
Then have the hasMany relationship on User e.g.
class User {
String name
static hasMany = [books: Book]
}
Then you can look Books up with criteria like:
def user = User.findByName( 'bob' )
def results = Book.createCriteria().list () {
eq( "user", user )
order( "createdDateTime", "desc" )
}

How to find from array list in one-many relationship

I have one-many 2 of domain class,
class Company {
String name
static hasMany = [groups:CompanyGroup]
}
class CompanyGroup {
String name
static belongsTo = [company:Company]
}
I receive a list of CompanyGroup from below code,
def groupList = CompanyGroup.withCriteria{
users{
eq 'id', new Long(user.id)
}
}
And I want to find which Companies has these groupList. I try this way,
def comList
groupList.each(){ group ->
def coms = Company.withCriteria{
eq("groups", group)
}
comList.collect{[coms]}
}
println 'company : ' + comList
It didn't work anymore.
How about this hql
Company.executeQuery("select c from company c join c.groups g join g.users u where u.id = :uid", [uid:xxx])
You could use this GORM Query.
def companyInstanceList = Company.createCriteria().listDistinct{
groups{
users{
eq ('id', user.id.toLong())
}
}
}

How to limit the size of association in grails?

I have a grails domain class as below :
class Order {
String orderId = 'OD' + System.nanoTime().toString()
Date orderedDate
String itemName
List bids;
static hasMany = [ bids: Bid ;likedUsers: User,]
static belongsTo =[owner:User]
}
class Bid {
Integer amount
User bidedUser
static belongsTo = [Order]
}
class User {
String username
String password
String emailId
List orders
static hasMany = [orders:Order]
}
What I am trying to do is , to query for an order with bits with maxResult of 10 as like
def critObj = Order.createCriteria()
critObj.list{
eq("id" ,1)
bids {
maxResult(10) //Trying to fetch only 10 records
}
}
How can I load only 10 bits(associations) , is it possible? . Or My design of domain class is wrong?
I think this should work:
def results = Bid.withCriteria {
order {
eq 'id', 1
}
projections {
property 'order'
}
maxResults 10
}
But please note that you have to change your Bid domain class to add the relation in the other way from Bid to Order:
class Bid {
...
static belongsTo = [order: Order]
}

Equals object criteria query

If I have two domain classes like this:
class Company{
string Name
string address
}
class User {
string firstName
string lastName
Company company
}
How can I get all the users from company named Google using criteria query? Something like this:
def company = Company.findByName("Google")
def c = User.createCriteria()
def usersByCompany = c.list {
eq("company", company)
}
You can declare a block inside your closure to filter any field in the Company:
def usersOfGoogle = User.createCriteria().list() {
company {
eq('name', 'Google')
}
}
I just don't remember if it works only for relationships (belongsTo & hasMany), maybe you will need to change your domain class:
class User {
static belongsTo = [company : Company]
}

Grails: Paging and Sorting over the collection in a relationship

I'd like to do paging and sorting from a collection in a relationship
For example with the following model:
class User {
String userName, password
static hasMany = [roles: UserRole, preferences: Preference]
}
class UserRole {
String name, description
static hasMany = [actions: Action]
}
I'd like to recover all the roles for a specific user. I already have the user loaded so the normal way to do it would be using
user.roles
But I want to sort them by UserRole properties and I want to paginate them dynamically
I know that if I want to get all the UserRoles sorted and paginated I can use:
UserRole.list([sort: 'name', order: 'asc',max: 5,offset:0])
But I want to do it just for the roles that are associated to my user. I was trying to use criteria, but I think I'm missing something.
I also had a look here:
http://grails.1312388.n4.nabble.com/A-Relationship-Paging-Pattern-td1326643.html
But then I would have to add the relation back into UserRole so I would have:
static hasMany = [users : UserRole]
How can I do this? what would be the best way?
Please, let me know if you need more information and sorry if I wasn't clear enough
Thanks and regards
You cannot paginate an "ordinary" relationship.
You can change the order child objects appear in using mapping DSL:
static mapping = {
sort name:desc
}
To simplify a hand-crafted paginated relationship, you can use a named query:
class Role {
static namedQueries = {
userRoles {
eq('user', UserSessionService.instance.currentUser)
}
}
}
Or you can implement a transient User's property that will return a Criteria for User's Roles (which can be paginated).
Grails Pagination with hasmany relation Bidirectional property finally i come to the point were i found it working Huuuh.
These are the Domain classes
class Client {
List bills
String shopName
String nameOfClient
static hasMany = [bills: Bill]
static constraints = {
shopName(blank:true, nullable:true)
nameOfClient(blank:false, nullable:false)
}
}
class Bill {
String billDetails
String billNo
static belongsTo = [client: Client]
static constraints = {
billDetails(blank:true, nullable:true , type: 'text')
billNo(blank:true, nullable:true)
}
}
Now This is my controller Logic
def clientDetails(){
def maxJobs = 4
def offset = (params?.offset) ?: 0
def clientId = params.id
def bills = Client.get(clientId).bills
def client= Client.get(clientId)
def results = Bill.withCriteria {
eq('client', client)
firstResult(offset as Integer)
maxResults(maxJobs)
}
[id:client.id,bills: results, offset: offset, max: maxJobs, totalJobs: bills.size()]
}
And the gsp code
<g:each in="${bills}">
<tr>
<td>${it.billNo}</td>
<td>${it.billDetails}</td>
</tr>
</g:each>
<g:paginate class="pagination" controller="client" action="clientDetails" total="${totalJobs?:0}" offset="${offset}" max="${max}" params="[id:"${id}"]"
prev="« Previous" next="Next »" />

Resources