加入不懒惰的问题;)
Problems with a join not being lazy ;)
在我的模型中,我有一个包含许多数据集的批处理,每个数据集都有许多文件,一个文件有许多源文件。
我们检索数据集也检索源文件
一长串 selects,即使我没有请求 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 与文件的连接:
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=?
正如我所说,我不需要源文件,但是没关系,让我们用一个查询来检索它们:
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.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)
真不知道怎么回事。有什么想法吗?
抱歉,我还不能对原始问题添加评论....
看看这个维基。我现在正在做一个多对多的关系,现在才了解它。
https://grails.org/wiki/Many-to-Many%20Mapping%20without%20Hibernate%20XML
惰性初始化错误
使用此技术时,您可能会遇到 Hibernate 延迟初始化错误,尤其是当您尝试从 GSP 模板内部访问您的域集合时(通过 GSP 页面中的渲染模板命令)。有一个解决方法。
首先,使用 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 -->
在模板中的第一个之前插入以上内容(它应该是 charEncodingFilter)。
它
结果发现问题是由为测试目的引入的注解引起的。域 class 文件顶部有这个:
@实体
@EqualsAndHashCode
如果我删除@EqualsAndHashCode,sourceFiles 选择消失,如果我添加
fetchMode "files.sourceFiles", org.hibernate.FetchMode.JOIN
对于标准,我不再有空指针异常了。
对我来说,这看起来像是一个错误,或者至少是必须详细记录的错误。
在我的模型中,我有一个包含许多数据集的批处理,每个数据集都有许多文件,一个文件有许多源文件。 我们检索数据集也检索源文件 一长串 selects,即使我没有请求 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 与文件的连接:
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=?
正如我所说,我不需要源文件,但是没关系,让我们用一个查询来检索它们:
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.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)
真不知道怎么回事。有什么想法吗?
抱歉,我还不能对原始问题添加评论.... 看看这个维基。我现在正在做一个多对多的关系,现在才了解它。
https://grails.org/wiki/Many-to-Many%20Mapping%20without%20Hibernate%20XML
惰性初始化错误
使用此技术时,您可能会遇到 Hibernate 延迟初始化错误,尤其是当您尝试从 GSP 模板内部访问您的域集合时(通过 GSP 页面中的渲染模板命令)。有一个解决方法。
首先,使用 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 -->
在模板中的第一个之前插入以上内容(它应该是 charEncodingFilter)。 它
结果发现问题是由为测试目的引入的注解引起的。域 class 文件顶部有这个: @实体 @EqualsAndHashCode
如果我删除@EqualsAndHashCode,sourceFiles 选择消失,如果我添加 fetchMode "files.sourceFiles", org.hibernate.FetchMode.JOIN 对于标准,我不再有空指针异常了。
对我来说,这看起来像是一个错误,或者至少是必须详细记录的错误。