gpt4 book ai didi

java - Hibernate:尝试保留对象图时出现 java.lang.StackOverflowError

转载 作者:行者123 更新时间:2023-11-29 08:52:38 24 4
gpt4 key购买 nike

我在尝试在数据库中保持多对一关系时遇到困难。我的方法对我来说似乎是合乎逻辑的,但是 hibernate 以 java.lang.StackOverflowError 打我的脸。让我来说明一下起始情况:

Relationship of Account and Person

Account 和 Person 记录已经保存在数据库中,但是 Account 和 Person 仍然必须通过 account.setPerson(person); 之类的语句链接在一起 我尝试了以下代码。让我逐步向您介绍代码。

打开 session :

Session session = sessionFactory.openSession();
session.beginTransaction();

查询所有具有 to_attribute 的账户。此属性用于链接名为 from_attribute 的源属性。这些属性是从 xml 配置文件中获取的,并作为定义外键关系的基础。

List<Account> queried_accounts = HibernateUtils.queryList(
session.createQuery(""
+ "select distinct acc from Account as acc"
+ " inner join acc.accountAttributes as accAtt"
+ " inner join accAtt.aa_pk.attribut as attr"
+ " where attr.name='" + to_attribute + "'")
);

查询所有人员

List<Person> queried_persons = HibernateUtils.queryList(session.createQuery("from Person"));

将所有帐户与匹配的人联系在一起。如果一个人的 from_attribute 中的值等于 account 中的 to_attribute 的值,则此人匹配。我想这段代码会导致 StackOverflow,但我不确定为什么。首先,我认为这是因为许多对象在 session.getTransaction().commit() 之前被更改。但即使是 session.flush() 也没有成功。我知道,这段代码不是很聪明。它导致“帐户记录数量”x“人员记录数量”读取操作加上相同数量的相等检查。因此,它的运行时复杂度为 O(n^2)。如我错了请纠正我。

for (Account account : queried_accounts) {
String account_to_attribut_wert = account.getAttributeValue(to_attribute);
for (Person person : queried_persons) {
if (person.getAttributeValue(from_attribute).equals(account_to_attribut_wert)) {
account.setPerson(person);
// session.flush();
}
}

}

session.getTransaction().commit();
session.close();

那么,你能帮我解决这个问题吗?我不知道如何避免 StackOverflowError

这是堆栈跟踪(此跟踪很长,但始终包含相同的文本)。

java.lang.StackOverflowError at org.hibernate.internal.SessionImpl.getLoadQueryInfluencers(SessionImpl.java:2071) at org.hibernate.engine.spi.QueryParameters.processFilters(QueryParameters.java:481) at org.hibernate.loader.plan.exec.internal.AbstractLoadPlanBasedLoader.executeQueryStatement(AbstractLoadPlanBasedLoader.java:188) 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.entity.plan.AbstractLoadPlanBasedEntityLoader.load(AbstractLoadPlanBasedEntityLoader.java:186) at org.hibernate.persister.entity.AbstractEntityPersister.load(AbstractEntityPersister.java:4120) at org.hibernate.event.internal.DefaultLoadEventListener.loadFromDatasource(DefaultLoadEventListener.java:502) at org.hibernate.event.internal.DefaultLoadEventListener.doLoad(DefaultLoadEventListener.java:467) at org.hibernate.event.internal.DefaultLoadEventListener.load(DefaultLoadEventListener.java:212) at org.hibernate.event.internal.DefaultLoadEventListener.proxyOrLoad(DefaultLoadEventListener.java:274) at org.hibernate.event.internal.DefaultLoadEventListener.onLoad(DefaultLoadEventListener.java:150) at org.hibernate.internal.SessionImpl.fireLoad(SessionImpl.java:1066) at org.hibernate.internal.SessionImpl.internalLoad(SessionImpl.java:985) at org.hibernate.type.EntityType.resolveIdentifier(EntityType.java:673) at org.hibernate.type.EntityType.resolve(EntityType.java:489) at org.hibernate.type.ComponentType.resolve(ComponentType.java:668) at org.hibernate.loader.plan.exec.process.internal.EntityReferenceInitializerImpl.resolveEntityKey(EntityReferenceInitializerImpl.java:158) at org.hibernate.loader.plan.exec.process.internal.AbstractRowReader.resolveEntityKey(AbstractRowReader.java:148) at org.hibernate.loader.plan.exec.process.internal.AbstractRowReader.readRow(AbstractRowReader.java:97) at org.hibernate.loader.plan.exec.internal.EntityLoadQueryDetails$EntityLoaderRowReader.readRow(EntityLoadQueryDetails.java:255) at org.hibernate.loader.plan.exec.process.internal.ResultSetProcessorImpl.extractResults(ResultSetProcessorImpl.java:129) 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.entity.plan.AbstractLoadPlanBasedEntityLoader.load(AbstractLoadPlanBasedEntityLoader.java:186) at org.hibernate.persister.entity.AbstractEntityPersister.load(AbstractEntityPersister.java:4120) at org.hibernate.event.internal.DefaultLoadEventListener.loadFromDatasource(DefaultLoadEventListener.java:502) at org.hibernate.event.internal.DefaultLoadEventListener.doLoad(DefaultLoadEventListener.java:467) at org.hibernate.event.internal.DefaultLoadEventListener.load(DefaultLoadEventListener.java:212) at org.hibernate.event.internal.DefaultLoadEventListener.proxyOrLoad(DefaultLoadEventListener.java:274) at org.hibernate.event.internal.DefaultLoadEventListener.onLoad(DefaultLoadEventListener.java:150) at org.hibernate.internal.SessionImpl.fireLoad(SessionImpl.java:1066) at org.hibernate.internal.SessionImpl.internalLoad(SessionImpl.java:985) at org.hibernate.type.EntityType.resolveIdentifier(EntityType.java:673) at org.hibernate.type.EntityType.resolve(EntityType.java:489) at org.hibernate.type.ComponentType.resolve(ComponentType.java:668)

最佳答案

我相信造成这种情况的唯一原因可能是递归调用。您绝对应该尝试删除那些递归调用,但对于您的问题,请尝试将查询的刷新模式设置为 FlushModeType.COMMIT。

由于是 StackOverflow 的缘故,如果无论如何都必须使用该递归调用,您也可以使用 Xss JVM 选项增加堆栈大小。

关于java - Hibernate:尝试保留对象图时出现 java.lang.StackOverflowError,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21954314/

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