我试图在数据库中保持多对一的关系时陷入困境。我的方法对我来说似乎是合乎逻辑的,但是hibernate用java.lang.StackOverflowError
打我的脸。让我来说明起始情况:
帐户和人员记录已在数据库中保留,但是帐户和人员仍然必须通过account.setPerson(person);
之类的语句链接在一起我尝试了以下代码。让我一步一步地向您介绍代码。
打开会话:
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中的值等于帐户中to_attribute的值,则匹配。
我想这段代码会导致StackOverflow,但我不知道为什么。首先,我认为它是由于事实,许多对象在session.getTransaction().commit()
之前被改变了。但即使session.flush()
也没有做到这一点。
我知道,这段代码不是很聪明。它会导致&#34;账户金额记录&#34; x&#34;人员记录数量&#34;读取操作加上相同数量的相同检查。因此,它的运行时复杂度为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) 在 org.hibernate.engine.spi.QueryParameters.processFilters(QueryParameters.java:481) 在 org.hibernate.loader.plan.exec.internal.AbstractLoadPlanBasedLoader.executeQueryStatement(AbstractLoadPlanBasedLoader.java:188) 在 org.hibernate.loader.plan.exec.internal.AbstractLoadPlanBasedLoader.executeLoad(AbstractLoadPlanBasedLoader.java:137) 在 org.hibernate.loader.plan.exec.internal.AbstractLoadPlanBasedLoader.executeLoad(AbstractLoadPlanBasedLoader.java:102) 在 org.hibernate.loader.entity.plan.AbstractLoadPlanBasedEntityLoader.load(AbstractLoadPlanBasedEntityLoader.java:186) 在 org.hibernate.persister.entity.AbstractEntityPersister.load(AbstractEntityPersister.java:4120) 在 org.hibernate.event.internal.DefaultLoadEventListener.loadFromDatasource(DefaultLoadEventListener.java:502) 在 org.hibernate.event.internal.DefaultLoadEventListener.doLoad(DefaultLoadEventListener.java:467) 在 org.hibernate.event.internal.DefaultLoadEventListener.load(DefaultLoadEventListener.java:212) 在 org.hibernate.event.internal.DefaultLoadEventListener.proxyOrLoad(DefaultLoadEventListener.java:274) 在 org.hibernate.event.internal.DefaultLoadEventListener.onLoad(DefaultLoadEventListener.java:150) 在org.hibernate.internal.SessionImpl.fireLoad(SessionImpl.java:1066) 在 org.hibernate.internal.SessionImpl.internalLoad(SessionImpl.java:985) 在 org.hibernate.type.EntityType.resolveIdentifier(EntityType.java:673) 在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) 在 org.hibernate.loader.plan.exec.process.internal.AbstractRowReader.resolveEntityKey(AbstractRowReader.java:148) 在 org.hibernate.loader.plan.exec.process.internal.AbstractRowReader.readRow(AbstractRowReader.java:97) 在 org.hibernate.loader.plan.exec.internal.EntityLoadQueryDetails $ EntityLoaderRowReader.readRow(EntityLoadQueryDetails.java:255) 在 org.hibernate.loader.plan.exec.process.internal.ResultSetProcessorImpl.extractResults(ResultSetProcessorImpl.java:129) 在 org.hibernate.loader.plan.exec.internal.AbstractLoadPlanBasedLoader.executeLoad(AbstractLoadPlanBasedLoader.java:138) 在 org.hibernate.loader.plan.exec.internal.AbstractLoadPlanBasedLoader.executeLoad(AbstractLoadPlanBasedLoader.java:102) 在 org.hibernate.loader.entity.plan.AbstractLoadPlanBasedEntityLoader.load(AbstractLoadPlanBasedEntityLoader.java:186) 在 org.hibernate.persister.entity.AbstractEntityPersister.load(AbstractEntityPersister.java:4120) 在 org.hibernate.event.internal.DefaultLoadEventListener.loadFromDatasource(DefaultLoadEventListener.java:502) 在 org.hibernate.event.internal.DefaultLoadEventListener.doLoad(DefaultLoadEventListener.java:467) 在 org.hibernate.event.internal.DefaultLoadEventListener.load(DefaultLoadEventListener.java:212) 在 org.hibernate.event.internal.DefaultLoadEventListener.proxyOrLoad(DefaultLoadEventListener.java:274) 在 org.hibernate.event.internal.DefaultLoadEventListener.onLoad(DefaultLoadEventListener.java:150) 在org.hibernate.internal.SessionImpl.fireLoad(SessionImpl.java:1066) 在 org.hibernate.internal.SessionImpl.internalLoad(SessionImpl.java:985) 在 org.hibernate.type.EntityType.resolveIdentifier(EntityType.java:673) 在org.hibernate.type.EntityType.resolve(EntityType.java:489)at org.hibernate.type.ComponentType.resolve(ComponentType.java:668)
答案 0 :(得分:0)
我相信唯一的原因导致这可能是递归调用。 您一定要尝试删除那些递归调用,但是对于您的问题,请尝试将查询的刷新模式设置为FlushModeType.COMMIT。
由于它是由StackOverflow引起的,如果必须使用该递归调用,也可以使用Xss JVM选项增加堆栈大小。