Grails: Projecting onto many tables?

I have some projection issues in Grails. Could you help me look through them and suggest solutions for me?

  • I want to query data in many tables that have many, one relationships and projection onto some properties on both of them. For example:

    class Person { int id String name String address static hasMany = [cars : Car] } class Car { int id String brand long price Person owner static belongsTo = [owner : Person] } 

    So, how can I use only one withCriteria request (apply projection) to get information about the specified car (including brand, price and owner name)? Is it possible to use:

     Car.withCriteria { projections { property("brand") property("price") property("owner.name") } eq("id", carId) } 
  • Can I use the projection to get the information of one specified person along with the name of all his cars? For example: [01, Perter, 01 Street A, [Mercedes, Toyota, Ducatti]]?

  • Exception: (with Person class above)
    A person can join many organizations, and an Organization can have one "parent" organization (and vice versa, an Organization can have many other dependent organizations). But there is a rule: a person can join only one subsidiary of this organization. So with this organization O and person P, what is the fastest way to get information P along with the name of the dependent organization O, which has P as a member. I prefer to use the Grail projection.

    Here's the data model:

     class Person { int id String name String address static hasMany = [joinedOrgs : Organization] } class Organization { int id String name Organization parentOrg static hasMany = [members : Person, childOrgs : Organization] } 

I am new to Grails and I would like to understand GORM more. Thank you so much for your help.

+8
grails gorm criteria projection
source share
3 answers

For (1) and (2), I don't know if there is a way to do what you want with just one query for criteria, but an alternative way just seems to be simpler and more natural. For (1):

 def car = Car.get(carId) def owners = car.owner?.name 

For (2)

 def person = Person.get(personId) def cars = person.cars*.name 

Oh (3), this is a design issue here. Your current domain design does not reflect the rule you are describing, so it will be difficult to maintain this restriction. You can map the PersonOrganization table and make the subsidiary an impassable property . For example:

 class Organization { int id String name Organization parent static transients = ['children'] ... Boolean children() { def children = Organization.createCriteria().list() { eq ('parent', this) } return children } } 

After that, you can use a tracking function such as getAllAncestors () to determine the entire parent hierarchy of the organization, see it in the list of personal organizations. This is not the best way, but it is possible.

+1
source share

try it

 def results = Car.createCriteria().list() { createAlias('owner','owner') projections { property('owner.name', 'owner.name') property('brand','brand') property('price','price') } } 
+10
source share

For (No. 1), I think you are looking here.

http://grails.1312388.n4.nabble.com/grails-reports-page-multiple-domain-criteria-join-td3510604.html

  def criteria = Company.createCriteria() def results = criteria.list { projections { property('id', 'company.id') ... POCs{ property('id', 'poc.id') property('name', 'poc.name') } software { productKey { ... } } ... order(company.name,'asc') } 

post emphasizes the use of .createCriteria()

+3
source share

All Articles