2015-09-17 19 views
1

我有一個域類Grails的標準動態和條件,一個一對多的關係

class Url { 
     UUID id 
     String url 
     static hasMany = [    
      indications:UrlIndication 
     ] 
     ... 
} 

而且

class UrlIndication { 
    UUID id 
    String name 

    static belongsTo = Url 
    ... 

} 

我想選擇的網址,以便它具有所有必要的UrlIndication元素給定的清單indicationsId。 對於我使用關聯and標準像這樣的:

indications { 
       and { 
         indicationsId.each{ 
          indication-> 
           eq ('id',UUID.fromString(indication as String)) 
         } 
        } 
      } 

然而,所有我得到的是一個空的結果。你可以提出任何修改/其他方法,以便我可以做到這一點?在此先感謝

回答

1

您的查詢返回一個空列表,因爲它是表達的當量(僞代碼):if 1 = 1 and 1 = 2 and 1 = 3

這樣的表達式將永遠是假。 ininList不會因爲@innovatism描述的原因。

理論上,Criteria的eqAll()或HQL的= ALL會起作用。 但是,我不知道,因爲我無法讓任何一個人工作。

工作原理是使用inList返回Urls的子集:那些至少包含一個UrlIndication ID的子集。然後使用Groovy的containsAll()完成這項工作。

def ids = indicationsId.collect { UUID.fromString(it as String) } 

Url.createCriteria() 
    .buildCriteria { 
     indications { 
      inList 'id', ids 
     } 
    } 
    .setResultTransformer(org.hibernate.Criteria.DISTINCT_ROOT_ENTITY) 
    .list() 
    .findAll { 
     it.indications.id.containsAll(ids) 
    } 

由於查詢必須返回重複Url情況的可能性,ResultTransformer設置返回唯一列表。

最後,findAll()containsAll()一起用於進一步過濾列表。

使用eqAll(可能)

類似以下內容可能會起作用。 Grails的HibernateCriteriaBuilder會引起eqAll方法在根實體中查找屬性;完全忽略了子標準。所以下面直接使用Hibernate。它不適合我,但它儘可能的接近我。它讓我頭疼!

Url.createCriteria().buildCriteria {} 
    .createCriteria('indications', 'i') 
    .add(org.hibernate.criterion.Property.forName('i.id').eqAll(org.hibernate.criterion.DetachedCriteria.forClass(UrlIndication) 
     .add(org.hibernate.criterion.Restrictions.in('id', ids)) 
     .setProjection(org.hibernate.criterion.Property.forName('id')) 
    )) 
    .setResultTransformer(org.hibernate.Criteria.DISTINCT_ROOT_ENTITY) 
    .list() 

我遇到的問題是我無法讓Restrictions.in工作。 Restrictions.eq工作正常。

+0

最後,我採用了相同的方法,但是當我想使用paginate時,困擾了我。你有什麼建議嗎?非常感謝! – innovatism

+0

我剛剛意識到你是創新主義者。大聲笑!無論如何,您將無法使用此方法的GORM分頁,因爲在從GORM獲取結果後,將列表過濾掉時,偏移/最大值將變得毫無用處。你必須將最終名單分頁。我不確定這樣的實現是否已經存在。如果你還剩下一些鍵盤潤滑脂,我會用可能有用的東西更新我的答案。 –

+0

@innovatism,最近出現了一個類似這個問題的新問題。有一個HQL查詢可能適合你。看看:http://stackoverflow.com/questions/32856121/grails-how-to-best-construct-a-hibernate-criteria-builder-to-search-hasmany –

0

in條款應做到:

indications { 
    'in' 'id', indicationsId.collect{ UUID.fromString indication.toString() } 
} 
+0

這會讓你的網站擁有其中一個元素,或者兩者都有,而不是擁有所有這些元素的網址。 – innovatism