سؤال

Let's say we have 3 domain classes: 2 classes related with each other through a 3rd class.

Ok, some code:

class A {
     String subject
     String description

     static hasMany = [cs: C]

     static transients = ['numberOfCs']

     Long getNumberOfCs() {
         return cs.size()
     }
}

class B {
     String title
}

class C {
     A objectA
     B objectB

     static belongsTo = [a: A]
}

Pretty clear? I hope so. This work perfectly with my domain.

You can see the transient property numberOfCs, which is used to calculate the number of C instances related to my A object. And it works just fine.

The problem: listing all my A objects, I want to sort them by the number of relationships with C objects, but the transient property numberOfCs cannot be used for the scope.

How can I handle the situation? How can I tell GORM to sort the As list by numberOfCs as it would be a regular (non transient) field?

Thanks in advance.

هل كانت مفيدة؟

المحلول

I'm not sure that Grails' criteria do support this, as you need both to select the A object itself and aggregate by a child objects (C). That means grouping by all the A's fields, which is not done automatically.

If you only need some fields from A, you can group by them:

def instances = A.withCriteria {
  projections { 
    groupProperty('subject')
    count('cs', 'cCount')
  }
  order 'cCount'
}

otherwise you'll need to retrieve only ids and make a second query, like in this question.

Another way is to use derived properties like described here (not sure it will work though):

class A {
    static mapping = {
        numberOfCs formula: 'select count(*) from C where c.b_id = id'
    }
}

نصائح أخرى

I wouldn't consider your Problem GORM related but rather general Hibernate or even SQL related.

Take a look at the HQL Docu they are a lot of examples.

check the following HQL this pretty close what you are asking.

select mySortedAs from A mySortedAs left join mySortedAs.cs myCsOfA order by              
count(myCsOfA)

I think I saw somewhere that you also can do something like this myCsOfA.length or myCsOfA.size

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top