简体   繁体   中英

Grails criteria projections - return whole table AND the projections

I want to know if I can have a single createCriteria() call, that returns me the whole table, and some specified joined columns.

Something like this:

SELECT table1.*, table2.property1,table2.property2 FROM table1 WHERE ... INNER JOIN table2 .

I have a code similar to this:

MyDomainClass.createCriteria().list{
    createAlias("relationedObject", "relationedObjectAlias")
    condition1(...)
    condition2(...)
    condition3(...)
    projections{
        property("relationedObjectAlias.nestedProperty")
        property("someProperty")
        property("anotherProperty")
   }
}

It returns me an array of arrays, containing these 3 properties listed inside the projections closure. But what should I do to receive the whole MyDomainClass object row, AND the projections?

What I really need, actually, is an array containing the whole MyDomainClass object, and the nestedProperty from the relationedObject .

I know I could just do another createCriteria() call, without specifying the projections, and manually "join" them in code, but this looks ugly to me... any ideas?

I'm using grails 2.5.5

I don't think there is a way in Hibernate to accomplish what you are doing so (nothing in the documentation that I've seen) and since you are using a HibernateCriteriaBuilder , I would say no.

I think your alternative would be to have all of your domain class's properties defined within your projection, depending on how many properties are involved you could do this manually or with some help:

import org.codehaus.groovy.grails.commons.DefaultGrailsDomainClass
import org.hibernate.criterion.CriteriaSpecification

...

def propertyNames = new DefaultGrailsDomainClass(MyDomainClass.class).
    getPersistentProperties().
    findAll{ p -> !p.isOneToMany() }*.
    name

MyDomainClass.createCriteria().list{
    createAlias("relationedObject", "relationedObjectAlias")
    condition1(...)
    condition2(...)
    condition3(...)

    resultTransformer(CriteriaSpecification.ALIAS_TO_ENTITY_MAP)

    projections{
        property("relationedObjectAlias.nestedProperty")
        propertyNames.each{ pn ->
            property(pn, pn)    
        }
   }
}

I would not call it pretty but it may work for your situation; I tested it on several of my domain objects and it worked successfully. I'm using DefaultGrailsDomainClass because getPersistentProperties() is a method on a non-static method and I don't want to rely on any particular instance. I'm excluding any collections based on my own testing.

Rather than relying on an returned array and the position of properties within that array, I'm using the ALIAS_TO_ENTITY_MAP result transformer to return a map. I think this is generally a good idea anyways, especially when dealing with larger result sets; and I think it's absolutely critical if gathering the properties in an automated fashion. This does require the property(<String>, <String>) method call as opposed to just the `property()', with the 2nd argument being the map key.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM