我最近接管了另一个人的圣杯项目。
我正在使用Grails 3.2.11和Hibernate 4.3.10
我正在添加新功能,其中之一正在扩展数据模型。有带有标签的故事,我想将它们合并为Tagaliasgroups。所以我添加了:
import groovy.transform.EqualsAndHashCode
@EqualsAndHashCode
class TagAliasGroup {
Date created = new Date()
Set aliases
static hasMany = [aliases: Tag]
[...]
在标签类中,我提到了:
import groovy.transform.EqualsAndHashCode
@EqualsAndHashCode
class Tag {
String tag
Boolean promoted
Boolean isCategory
Date created = new Date()
TagAliasGroup aliasGroup
[...]
正确更新了DB-Schema,我可以编写新的数据集。但是,当试图访问TagaliasGroup设置的"别名"时,我在Hibernate内部得到无尽的递归,结果是堆叠的异常:
def getAliasList() {
try
{
if(aliasGroup)
{
Set al = aliasGroup.aliases
// al.remove(this)
return al.join(", ")
}
else return ""
}
catch(Exception e){
return e.getMessage()
}
}
"返回al.join(",")抛出异常,但是对集合的任何其他访问都具有相同的结果。试图评估" AL"时,调试器也会有例外。当那时踏入休眠状态时,当代码试图一遍又一遍地取消代理并解决代理时,它在我看来。
我通过使"别名"瞬态进行了简单的解决方法:
import groovy.transform.EqualsAndHashCode
@EqualsAndHashCode
class TagAliasGroup {
Date created = new Date()
// Set aliases
// static hasMany = [aliases: Tag]
def getAliases() {
return Tag.findAllByAliasGroup(this)
}
这很好地工作了,但不能是正确的解决方案。尤其是因为我希望冬眠会缓存结果并因此更有效。
我想念什么?这一定很明显,但我不知道什么。
这是例外:
java.lang.StackOverflowError: null
at org.apache.commons.logging.impl.SLF4JLocationAwareLog.isDebugEnabled(SLF4JLocationAwareLog.java:67)
at org.springframework.jdbc.datasource.LazyConnectionDataSourceProxy$LazyConnectionInvocationHandler.getTargetConnection(LazyConnectionDataSourceProxy.java:429)
at org.springframework.jdbc.datasource.LazyConnectionDataSourceProxy$LazyConnectionInvocationHandler.invoke(LazyConnectionDataSourceProxy.java:376)
at org.springframework.jdbc.datasource.TransactionAwareDataSourceProxy$TransactionAwareInvocationHandler.invoke(TransactionAwareDataSourceProxy.java:240)
at org.hibernate.engine.jdbc.internal.StatementPreparerImpl$5.doPrepare(StatementPreparerImpl.java:162)
at org.hibernate.engine.jdbc.internal.StatementPreparerImpl$StatementPreparationTemplate.prepareStatement(StatementPreparerImpl.java:186)
at org.hibernate.engine.jdbc.internal.StatementPreparerImpl.prepareQueryStatement(StatementPreparerImpl.java:160)
at org.hibernate.loader.plan.exec.internal.AbstractLoadPlanBasedLoader.prepareQueryStatement(AbstractLoadPlanBasedLoader.java:257)
at org.hibernate.loader.plan.exec.internal.AbstractLoadPlanBasedLoader.executeQueryStatement(AbstractLoadPlanBasedLoader.java:201)
at org.hibernate.loader.plan.exec.internal.AbstractLoadPlanBasedLoader.executeLoad(AbstractLoadPlanBasedLoader.java:137)
at org.hibernate.loader.plan.exec.internal.AbstractLoadPlanBasedLoader.executeLoad(AbstractLoadPlanBasedLoader.java:102)
at org.hibernate.loader.collection.plan.AbstractLoadPlanBasedCollectionInitializer.initialize(AbstractLoadPlanBasedCollectionInitializer.java:100)
at org.hibernate.persister.collection.AbstractCollectionPersister.initialize(AbstractCollectionPersister.java:693)
at org.hibernate.event.internal.DefaultInitializeCollectionEventListener.onInitializeCollection(DefaultInitializeCollectionEventListener.java:92)
at org.hibernate.internal.SessionImpl.initializeCollection(SessionImpl.java:1933)
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.codehaus.groovy.util.HashCodeHelper.updateHash(HashCodeHelper.java:84)
at org.codehaus.groovy.util.HashCodeHelper.updateHash(HashCodeHelper.java:84)
at java.util.HashMap.hash(HashMap.java:339)
at java.util.HashMap.put(HashMap.java:612)
at java.util.HashSet.add(HashSet.java:220)
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.plan.exec.process.internal.CollectionReferenceInitializerImpl.endLoading(CollectionReferenceInitializerImpl.java:168)
at org.hibernate.loader.plan.exec.process.internal.AbstractRowReader.finishLoadingCollections(AbstractRowReader.java:255)
at org.hibernate.loader.plan.exec.process.internal.AbstractRowReader.finishUp(AbstractRowReader.java:218)
at org.hibernate.loader.plan.exec.process.internal.ResultSetProcessorImpl.extractResults(ResultSetProcessorImpl.java:140)
at org.hibernate.loader.plan.exec.internal.AbstractLoadPlanBasedLoader.executeLoad(AbstractLoadPlanBasedLoader.java:138)
at org.hibernate.loader.plan.exec.internal.AbstractLoadPlanBasedLoader.executeLoad(AbstractLoadPlanBasedLoader.java:102)
at org.hibernate.loader.collection.plan.AbstractLoadPlanBasedCollectionInitializer.initialize(AbstractLoadPlanBasedCollectionInitializer.java:100)
at org.hibernate.persister.collection.AbstractCollectionPersister.initialize(AbstractCollectionPersister.java:693)
at org.hibernate.event.internal.DefaultInitializeCollectionEventListener.onInitializeCollection(DefaultInitializeCollectionEventListener.java:92)
at org.hibernate.internal.SessionImpl.initializeCollection(SessionImpl.java:1933)
从这里不断地重复。
我会以我的经验来说明这个答案,以我使用Hasmany,Altersto或任何其他预选赛的经验,这会导致更多的问题。除非您绝对需要它们提供的东西(级联,特定的休眠级缓存等)。只需坚持保留标签上的简单参考,然后从TagaliasGroup中删除" Hasmany",然后使用Dynamic Finder根据您的解决方法加载标签。也就是说,坚持您的设计,我认为您需要"属于",以避免给定标签的tagaliasgroup循环递归。
class Tag {
....
static belongsTo = [TagAliasGroup: aliasGroup]
....
}