2016-06-24 4 views
4

У меня есть проект фиктивного кафетерия, в котором у меня есть три класса домена: User, Product и Transaction.GORM создать критерии - использование предложения «having» SQL

Вот как классы определены:

class User { 

    String name 
    int employeeId 
    long balance = 800 
    static constraints = { 
     balance(max: 800L) 
    } 
} 

class Product { 

    String type 
    int quantityInStock 
    float price 
    static constraints = { 
    } 
} 

class Transaction { 

    int quantityBought 
    static belongsTo = [user: User, product: Product] 
    static constraints = { 
    } 
} 

Теперь я хочу узнать количество/список пользователей, которые купили больше, чем, скажем, 2 модели. Как это сделать, используя Grails createCriteria?

Это то, что я пробовал:

Transaction.createCriteria().list(){ 
    projections { 
     groupProperty('user') 
     'product' { 
      count('id','numberOfPurchases') 
     } 
    } 
    gt('numberOfPurchases',2) 
} 

Но это дает следующее сообщение об ошибке:

Stacktrace: 

org.hibernate.QueryException: could not resolve property: numberOfPurchases of: cafeteria.dummy.Transaction 
at grails.orm.HibernateCriteriaBuilder.invokeMethod(HibernateCriteriaBuilder.java:1618)      
at Script1.run(Script1.groovy:4)                   
at org.grails.plugins.console.ConsoleService.eval(ConsoleService.groovy:37)         
at org.grails.plugins.console.ConsoleController.execute(ConsoleController.groovy:59)      
at grails.plugin.cache.web.filter.PageFragmentCachingFilter.doFilter(PageFragmentCachingFilter.java:195) 
at grails.plugin.cache.web.filter.AbstractFilter.doFilter(AbstractFilter.java:63)       
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)       
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)       
at java.lang.Thread.run(Thread.java:745)                 

Как я могу получить доступ этот псевдоним numberOfPurchases вне проекций блок таким образом, чтобы использовать его в gt?

+0

Вы можете использовать вспомогательный запрос с HQL. Некоторые подробности приведены в разделе 7.4 http://docs.grails.org/latest/guide/GORM.html – Mamun

+0

@Mamun, я знаю, что это можно сделать с использованием HQL. Я хотел знать, можно ли это сделать с помощью критериев. –

+1

вы можете использовать DetachedCriteria, хотя, возможно, это не так, как вы, вероятно, ожидаете. – Mamun

ответ

2

Внутренний GORM использует Hibernate и в настоящее время Hibernate не поддерживает having clause в Criteria API. Причина, по которой вы не можете получить numberOfPurchases внешний блок прогнозов, заключается в том, что ограничения добавляются в предложение where, и вы не можете использовать псевдоним агрегации в статье where. Хотя JPA поддерживает предложение.

Но если вы все еще хотите достичь этого, используя критерии GORM, вы можете. Но вам придется немного изменить запрос, и это не будет включать использование предложения и потребует подзапроса.

Измененный запрос будет:

SELECT DISTINCT this_.user_id FROM transaction this_ where 2 < (SELECT count(sub_.id) FROM transaction sub_ WHERE sub_.user_id=this_.user_id) 

И GORM за это будет:

import org.hibernate.criterion.DetachedCriteria 
import org.hibernate.criterion.Projections 
import org.hibernate.criterion.Restrictions 
import org.hibernate.criterion.Subqueries 

DetachedCriteria subQuery = DetachedCriteria.forClass(Transaction, 'sub').with { 
    setProjection Projections.count('sub.id') 
    add Restrictions.eqProperty('sub.user', 'this.user') 
} 

List<User> users = Transaction.createCriteria().list() { 
    projections { 
     distinct("user") 
    } 
    add Subqueries.lt(2l, subQuery) 
} 
+0

Спасибо за информативное решение @Sandeep. Я на самом деле хотел уточнить, поддерживает ли «Критерии» предложение «having». –

+0

@SAKSHISINGHAL Нет, это не –

 Смежные вопросы

  • Нет связанных вопросов^_^