gpt4 book ai didi

hibernate - Grails:双向一对多导致无限递归(StackOverflow)

转载 作者:行者123 更新时间:2023-12-02 15:45:58 24 4
gpt4 key购买 nike

我最近从另一个人那里接手了一个 Grails 项目。

我正在使用 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]
[...]

在 Tag 类中,我提到了这一点:
import groovy.transform.EqualsAndHashCode

@EqualsAndHashCode
class Tag {
String tag
Boolean promoted
Boolean isCategory
Date created = new Date()

TagAliasGroup aliasGroup

[...]

DB-Schema 已正确更新,我可以很好地编写新数据集。但是,当尝试从 TagAliasGroup 访问“别名”集时,我在 Hibernate 内部得到了无休止的递归,结果是 StackOverflow 异常:
def getAliasList() {
try
{
if(aliasGroup)
{
Set al = aliasGroup.aliases
// al.remove(this)

return al.join(", ")
}
else return ""
}
catch(Exception e){
return e.getMessage()
}
}

"return al.join(", ")"会引发异常,但对 Collection 的任何其他访问都具有相同的结果。调试器在尝试评估“al”时也会出现异常。
那时进入 Hibernate 时,在我看来,代码会一遍又一遍地尝试取消引用和解析 TagAliasGroup 的代理。

我通过使“别名”瞬变做了一个简单的解决方法:
import groovy.transform.EqualsAndHashCode

@EqualsAndHashCode
class TagAliasGroup {
Date created = new Date()

// Set aliases
// static hasMany = [aliases: Tag]

def getAliases() {
return Tag.findAllByAliasGroup(this)
}

这是完美的工作,但它不是正确的解决方案。特别是因为我希望hibernate会缓存结果并因此更有效。

我错过了什么?这一定很明显,但我不知道是什么。

这是一个异常(exception):
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、belongsTo 或任何其他限定符的经验中说明这个答案会导致比它帮助更多的问题。除非您绝对需要它们提供的东西(级联、特定的 hibernate 级别缓存等)。只需坚持保留您对 Tag 的简单引用并从 TagAliasGroup 中删除“hasMany”,然后根据您的解决方法使用动态查找器加载标签。也就是说,坚持你的设计,我认为你需要'belongsTo'来避免给定标签的对 TagAliasGroup 的循环反向引用的递归。

class Tag {
....
static belongsTo = [TagAliasGroup: aliasGroup]
....
}

关于hibernate - Grails:双向一对多导致无限递归(StackOverflow),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47713244/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com