Hibernate:java.lang.StackOverflowError在尝试持久化对象图时

时间:2014-02-22 12:27:16

标签: java hibernate stack-overflow

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

Relationship of Account and Person

帐户和人员记录已在数据库中保留,但是帐户和人员仍然必须通过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)

1 个答案:

答案 0 :(得分:0)

我相信唯一的原因导致这可能是递归调用。 您一定要尝试删除那些递归调用,但是对于您的问题,请尝试将查询的刷新模式设置为FlushModeType.COMMIT。

由于它是由StackOverflow引起的,如果必须使用该递归调用,也可以使用Xss JVM选项增加堆栈大小。