Grails GORM: list all with nested property - grails

My (simplified) domain model looks like this:
class Student {
static hasMany = [professions:StudentProfession];
}
class StudentProfession {
static belongsTo = [student:Student];
Profession profession;
}
class Profession {
String name;
}
What is the most efficient way to:
List all students that are taught "Programmer" and "Manager" professions
Am I forced to filter them out after querying the database?
students = students.findAll { student ->
student.professions.find { professionNames.contains(it.profession.name) } != null
}

You can do this using a GORM query:
def studends = Student.where {
professions {
profession.name == "Programmer" || profession.name == "Manager"
}
}

Lots of ways to skin this cat - here's one:
StudentProfession.findAllByProfessionInList(Profession.findAllByNameInList(["Programmer","Manager"])*.student.unique()

Related

Deep object validation

I have 3 classes
class Company {
String company_name
}
class Job {
String job_name
Company company
}
class Person {
String person_name
Job job
}
How can I check if a position is really existing from an existing company and it is vacant (no Person is on it) or in other words there is existing Job object with existing Company of course but no Person has in his constructor passed this Job object, here is what I have done,where is my mistake ?
if (person==null && job != null && company != null)
{
def query=Job.where{company.company_name == company_name && job_name == job_name}
def query2=Person.where {job.job_name == job_name}
if( query == null && query2 != null )
{
def person12 = new Person(job: job, person_name: person_name)
if (person12.validate() && person12.save())
{
redirect(url: "https//localhost:8080")
}
}
I would relate the classes in other way if possible:
class Company {
String company_name
static hasMany = [jobs: Job]
}
class Job {
static belongsTo = [company: Company]
static hasOne = [person: Person]
String job_name
}
class Person {
String person_name
static belongsTo = [job: Job]
}
And then you can create a criteria to know if a job has no person related.
List<Job> jobs = Job.withCriteria{
eq('company', companyObject)
isNull('person')
}
You don't need to validate an object before save it, cause it automatly validated before, and if it is not valid, return false.
if (person12.save()) {
redirect(url: "https//localhost:8080")
}

How to convert native sql to grails/gorm

Can I convert this to GRAILS/GORM. If yes, any help please.
select b.id, b.username, b.first_name, b.last_name
from tb_user_orgpermissions a
inner join tb_user b on a.username = b.username
where
(a.department_id = :dept_id)
and (a.agency_id = :agy_id)
To create the equivalent query as a gorm criteria query, the first thing you need is domain classes (with proper associations) for each table. As an example, here's some pseudo code:
class User {
String username
String firstName
String lastName
static hasOne = [permission: UserPermission]
}
class UserPermission {
Department department
Agency agency
}
class Department {}
class Agency {}
In this example User has a one-to-one association to UserPermission.
With something like this in place you can create a criteria query (with projections):
User.withCriteria {
projections {
property 'id'
property 'username'
property 'firstName'
property 'lastName'
}
permission {
department {
eq 'id', dept_id
}
agency {
eq 'id', agy_id
}
}
}

Grails Gorm Query Restriction

I have two domains
class ProductQuantity {
Integer quantity
static belongsTo = [productSize: ProductSize]
}
class ProductSize {
String size
static hasMany = [productQuantities : ProductQuantity]
}
I'm trying to build a query where I get all ProductQuantity by the productSize. I have the following query that works.
def productSize = ProductSize.findAllById(1);
def productQuantities = ProductQuantity.findAllByProductSize(productSize)
I'm looking to get the ProductQuanties in a single query rather than two separate queries.
ProductQuantity.createCriteria().list {
eq 'productSize', ProductSize.load(1)
}
or
ProductQuantity.withCriteria {
eq 'productSize', ProductSize.load(1)
}
or
ProductQuantity.where {
productSize == ProductSize.load(1)
}.list()
or
ProductQuantity.findAll("from ProductQuantity where productSize = ?", [ProductSize.load(1)])
Yes, you can get this by createCriteria, like --
def productQuantities = ProductQuantity.createCriteria().list() {
productSize {
eq('id', 1)
}
}

Grails createCriteria on abstract domain

I am quite curious how one would use the criteria builder to access fields of an inherited class.
Let's assume we have the following class:
class A {
String fieldOne
String fieldTwo
static hasMany = [childs: AbstractChildClass]
}
and the abstract child class would look like this:
abstract class AbstractChildClass {
Integer valueOne
Integer valueTwo
A a
static mapping
tablePerHierarchy false
}
}
of course there are several extending classes such as:
class ExtendingClassOne extends AbstractChildClass {
DesiredObject desiredObject
static mapping = {
tablePerHierarchy false
}
}
let's also assume there is the class DesiredObject which looks like this:
class DesiredObject {
String infoA
String infoB
}
The question is how one would get the fields infoA and infoB by creating a criteria for class A. My approach so far is this:
A.createCriteria().list {
childs {
desiredObject {
ilike('infoA', '%something%')
}
}
}
This of course does not work because in the table ExtendingClassOne is only the id of the desiredObject and I have no clue how to join the object with the criteria builder to get its fields.
Thank you for reading.
Marco
don't expect 100% match between your domain model and the DB schema it's related to.
In your case the polymorphism would work only with tablePerHierarchy true for AbstractChildClass.
If you do want to stick with tablePerHierarchy false, you can define your class like:
class A {
static hasMany = [ childrenOne:ExtendingClassOne, childrenTwo:ExtendingClassTwo ]
}
thus your query would be as simple as:
A.withCriteria{
for( String c in [ 'childrenOne', 'childrenTwo' ] ){
"$c"{
desiredObject {
ilike('infoA', '%something%')
}
}
}
}

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]
}

Resources