连接问题不是懒惰;)

时间:2015-12-15 14:37:00

标签: grails gorm

在我的模型中,我有一个包含许多数据集的批处理,每个数据集都有很多文件,而一个文件有很多源文件。 我检索数据集也检索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)

我真的不知道发生了什么。有什么想法吗?

2 个答案:

答案 0 :(得分:0)

抱歉,我无法对原始问题添加评论.... 看看这个维基。我现在正在做多对多的关系并且刚刚开始学习它。

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

延迟初始化错误

使用此技术时可能会遇到Hibernate Lazy Initialization错误,尤其是当您尝试从GSP模板内部访问域集合时(通过GSP页面中的render template命令)。有一种解决方法。

首先,使用grails命令将grails模板安装到项目中:

grails install-templates

接下来,找到web.xml模板grails-app / src / templates / war / 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 -->

在模板中的第一个之前插入上面的JUST(它应该是charEncodingFilter)。 它

答案 1 :(得分:0)

结果是问题是由为测试purpouses引入的注释引起的。域类File在顶部有这个: @实体 @EqualsAndHashCode

如果我删除@EqualsAndHashCode,则sourceFiles选择消失,如果我添加 fetchMode“files.sourceFiles”,org.hibernate.FetchMode.JOIN 对于critera我不再有空指针异常。

对我而言,这看起来像是一个错误,或者至少需要记录下来的东西。