2015-12-15 30 views
1

在我的模型中,我有一個具有多個數據集的批處理,每個數據集有許多文件和一個文件hasMany sourceFiles。 我們檢索數據集也檢索源文件與 一長串選擇,即使我沒有請求sourceFiles,或至少這是我的想法。連接不是懶惰的問題;)

這是我的簡化模型,我刪除了所有非有趣的東西。

class Batch { 
    static hasMany = [ datasets : Dataset] 
} 

class Dataset { 
    File mainFile 
    Batch batch 

    static hasMany = [files : File] 
    static mapping = { 
     files column:"dataset_id" 
    files joinTable:[name:"${Constants.phase3DB}${Constants.schemaName}.datasets_files"] 
    files fetch:'join' 
    } 
} 


class File { 
    static hasMany = [ sourceFiles: String ] 
    static mapping = { 
    sourceFiles joinTable: [name: 
    "${Constants.phase3DB}${Constants.schemaName}.provenance", 
    key:'product_file', column:'source_file', type:'text'] 
    } 
} 

這是我在我的服務:

Batch batch = Batch.get(batchId) 
def datasets = Dataset.withCriteria { 
    eq "batch", batch 
    fetchMode "files", org.hibernate.FetchMode.JOIN 
} 
batch.datasets = datasets 

這樣做我可以看到一個選擇了加入到文件:

select this_.dataset_id as dataset_1_14_1_, this_.active as active2_14_1_, this_.batch_id as batch_id3_14_1_, this_.deprecation_date as deprecat4_14_1_, this_.group_id as group_id5_14_1_, this_.version as version6_14_1_, this_.main_file_id as main_fil7_14_1_, files2_.dataset_id as dataset_1_14_3_, file3_.file_id as file_id2_15_3_, file3_.file_id as file_id1_18_0_, file3_.archive_id as archive_2_18_0_, file3_.archived as archived3_18_0_, file3_.catalog_extracted as catalog_4_18_0_, file3_.category as category5_18_0_, file3_.checksum as checksum6_18_0_, file3_.keywords_extracted as keywords7_18_0_, file3_.name as name8_18_0_, file3_.processing_date as processi9_18_0_, file3_.size as size10_18_0_ 
from phase3v2.dbo.datasets this_ 
left outer join phase3v2.dbo.datasets_files files2_ on this_.dataset_id=files2_.dataset_id 
left outer join phase3v2.dbo.files file3_ on files2_.file_id=file3_.file_id 
where this_.batch_id=?; 

但緊接着我看到一個長這樣的查詢列表:

select sourcefile0_.product_file as product_1_18_0_, 
sourcefile0_.source_file as source_f2_20_0_ from phase3v2.dbo.provenance 
sourcefile0_ where sourcefile0_.product_file=? 

正如我說我不需要sourceFiles,但細,讓我們找回它們與一個單一的查詢:

Batch batch = Batch.get(batchId) 
def datasets = Dataset.withCriteria { 
    eq "batch", batch 
    fetchMode "files", org.hibernate.FetchMode.JOIN 
    fetchMode "files.sourceFiles", org.hibernate.FetchMode.JOIN 
} 
batch.datasets = datasets 

這樣做我有一個空指針異常。

java.lang.NullPointerException 

at 
org.hibernate.engine.internal.StatefulPersistenceContext.getLoadedCollectionOwnerOrNull(StatefulPersistenceContext.java:752) 

at 
org.hibernate.event.spi.AbstractCollectionEvent.getLoadedOwnerOrNull(AbstractCollectionEvent.java:75) 

at 
org.hibernate.event.spi.InitializeCollectionEvent.<init>(InitializeCollectionEvent.java:36) 

at 
org.hibernate.internal.SessionImpl.initializeCollection(SessionImpl.java:1895) 

at 
org.hibernate.collection.internal.AbstractPersistentCollection$4.doWork(AbstractPersistentCollection.java:558) 

at 
org.hibernate.collection.internal.AbstractPersistentCollection.withTemporarySessionIfNeeded(AbstractPersistentCollection.java:260) 

at 
org.hibernate.collection.internal.AbstractPersistentCollection.initialize(AbstractPersistentCollection.java:554) 

at 
org.hibernate.collection.internal.AbstractPersistentCollection.read(AbstractPersistentCollection.java:142) 

at 
org.hibernate.collection.internal.PersistentSet.hashCode(PersistentSet.java:447) 

at org.eso.phase3.rm.File.hashCode(File.groovy) 

at java.util.HashMap.hash(HashMap.java:338) 

at java.util.HashMap.put(HashMap.java:611) 

at java.util.HashSet.add(HashSet.java:219) 

at java.util.AbstractCollection.addAll(AbstractCollection.java:344) 

at 
org.hibernate.collection.internal.PersistentSet.endRead(PersistentSet.java:344) 

at 
org.hibernate.engine.loading.internal.CollectionLoadContext.endLoadingCollection(CollectionLoadContext.java:251) 

at 
org.hibernate.engine.loading.internal.CollectionLoadContext.endLoadingCollections(CollectionLoadContext.java:238) 

at 
org.hibernate.engine.loading.internal.CollectionLoadContext.endLoadingCollections(CollectionLoadContext.java:211) 

at org.hibernate.loader.Loader.endCollectionLoad(Loader.java:1156) 

at 
org.hibernate.loader.Loader.initializeEntitiesAndCollections(Loader.java:1125) 

at org.hibernate.loader.Loader.processResultSet(Loader.java:972) 

at org.hibernate.loader.Loader.doQuery(Loader.java:920) 

at 
org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:354) 

at org.hibernate.loader.Loader.doList(Loader.java:2553) 

at org.hibernate.loader.Loader.doList(Loader.java:2539) 

at org.hibernate.loader.Loader.listIgnoreQueryCache(Loader.java:2369) 

at org.hibernate.loader.Loader.list(Loader.java:2364) 

at 
org.hibernate.loader.criteria.CriteriaLoader.list(CriteriaLoader.java:126) 

at org.hibernate.internal.SessionImpl.list(SessionImpl.java:1682) 

at org.hibernate.internal.CriteriaImpl.list(CriteriaImpl.java:380) 

at 
org.grails.datastore.gorm.GormStaticApi$_withCriteria_closure11.doCall(GormStaticApi.groovy:305) 

at 
org.springsource.loaded.ri.ReflectiveInterceptor.jlrMethodInvoke(ReflectiveInterceptor.java:1270) 

at com.sun.proxy.$Proxy47.doInSession(Unknown Source) 

at 
org.grails.datastore.mapping.core.DatastoreUtils.execute(DatastoreUtils.java:302) 

at 
org.grails.datastore.gorm.AbstractDatastoreApi.execute(AbstractDatastoreApi.groovy:37) 

at 
org.grails.datastore.gorm.GormStaticApi.withCriteria(GormStaticApi.groovy:304) 

at org.eso.phase3.rm.Dataset.withCriteria(Dataset.groovy) 

at org.eso.phase3.rm.Dataset$withCriteria.call(Unknown Source) 

at ConsoleScript0.run(ConsoleScript0:4) 

at 
org.springsource.loaded.ri.ReflectiveInterceptor.jlrMethodInvoke(ReflectiveInterceptor.java:1270) 

我真的不知道發生了什麼事情。任何想法?

+0

條件中的文件抓取:'join''在域類和'fetchMode「文件中,org.hibernate.FetchMode.JOIN'將始終導致對相關結果的急切抓取。如果你想加入懶惰,你需要在領域類中獲取:'SELECT''(如果沒有指定,這是默認行爲),'fetchMode'作爲SELECT。請參閱[fetch]的文檔(https://grails.github.io/grails-doc/3.0.x/ref/Database%20Mapping/fetch.html)和[fetchMode](https://grails.github.io/ grails-doc/3.0.x/guide/GORM.html) – dmahapatro

+0

我之前做過,沒有改變,但我認爲我發現了這個問題。 我會爲這篇文章添加一個答案,並將在github上打開一張票。 感謝您的時間! –

回答

0

抱歉,我還沒有添加評論爲原始問題呢.... 看看這個wiki吧。我現在正在做一個多對多的關係,並剛剛瞭解它。

https://grails.org/wiki/Many-to-Many%20Mapping%20without%20Hibernate%20XML

懶惰初始化錯誤

使用這種技術時,尤其是當你試圖從內部GSP模板訪問您的域集合您可能會遇到的Hibernate的延遲初始化錯誤(通過GSP頁面渲染模板命令)。有一個解決方法。

首先,使用Grails命令到Grails的模板安裝到您的項目:

grails install-templates 

接下來,找到web.xml模板,在grails-app/src目錄/模板/戰爭/ web.xml文件。

添加以下內容:

<!-- Hibernate --> 
<filter> 
    <filter-name>hibernateFilter</filter-name> 
    <filter-class> 
    org.codehaus.groovy.grails.orm.hibernate.support.GrailsOpenSessionInViewFilter 


</filter-class> 
</filter> 
<filter-mapping> 
    <filter-name>hibernateFilter</filter-name> 
    <url-pattern>/*</url-pattern> 
</filter-mapping> 
<!-- ~ Hibernate --> 

插入上述之前在模板中的第一個(應該是charEncodingFilter)。 It

0

這個問題是由引入測試紫外線的註釋引起的。該域類文件有這樣之上: @Entity @EqualsAndHashCode

如果我刪除@EqualsAndHashCode的sourceFiles將選擇消失,如果我添加 fetchMode「files.sourceFiles」,org.hibernate.FetchMode.JOIN 到critera我沒有空指針異常了。

對我來說,這看起來像一個錯誤或至少是必須非常好的記錄。