簡體   English   中英

休眠:嘗試持久化對象圖時發生java.lang.StackOverflowError

[英]Hibernate: java.lang.StackOverflowError while trying to persist an object graph

我在嘗試在數據庫中保持多對一關系時遇到了麻煩。 我的方法對我來說似乎是合乎邏輯的,但是休眠方式卻帶有java.lang.StackOverflowError 讓我說明開始的情況:

帳戶與人的關系

Account和Person記錄已經保留在數據庫中,但是Account和Person仍必須通過諸如account.setPerson(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()也無法解決問題。 我知道,這段代碼不是很聰明。 這將導致“帳戶記錄數量” 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

這是堆棧跟蹤(此跟蹤很長,但始終包含相同的文本)。

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

我相信導致此問題的唯一原因可能是遞歸調用。 您絕對應該嘗試刪除這些遞歸調用,但是對於您的問題,請嘗試將查詢的刷新模式設置為FlushModeType.COMMIT。

由於這是由於StackOverflow引起的,因此如果您仍然必須使用該遞歸調用,則還可以使用Xss JVM選項來增加堆棧大小。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM