由于嵌入式组件的递归,Hibernate refresh()会导致堆栈溢出

时间:2011-12-02 09:08:16

标签: hibernate components refresh stack-overflow

我有一个遗留数据库,我试图使用Hibernate 3进行访问。

在这个数据库中,我有两个实体: A B ,第三个实体 C 代表 A <之间的关系/ strong>和 B C 实体还包含有关该关系的一些其他信息,因此无法将其编码为@ManyToMany。

C 实体使用@Id和@ManyToOne注释引用 A B 实体。 A B 实体使用@OneToMany批注将 C 实体列为集合。

底层数据库可能会发生变化,因此我尝试使用Hibernate refresh()过程从数据库中重新读取 A 实体的数据。

这导致无休止的递归循环: A - &gt; C - &gt; A - &gt; C ...导致堆栈溢出。

似乎这个 refresh()过程尝试刷新每个引用,包括惰性的引用,具有无限深度。这对我来说并不是真的有必要,如果我可以进行“浅层”刷新并将所有@OneToMany设置重置回“未初始化”状态就足够了。

所以我的问题是:

我如何避免这种无休止的递归

我怎样才能将某个实体“重置”回“未初始化”状态

下面是使用Eclipse生成的堆栈跟踪的一部分。

SingleTableEntityPersister(AbstractEntityPersister).load(Serializable, Object, LockOptions, SessionImplementor) line: 3293
DefaultLoadEventListener.loadFromDatasource(LoadEvent, EntityPersister, EntityKey, LoadEventListener$LoadType) line: 496
DefaultLoadEventListener.doLoad(LoadEvent, EntityPersister, EntityKey, LoadEventListener$LoadType) line: 477
DefaultLoadEventListener.load(LoadEvent, EntityPersister, EntityKey, LoadEventListener$LoadType) line: 227
DefaultLoadEventListener.proxyOrLoad(LoadEvent, EntityPersister, EntityKey, LoadEventListener$LoadType) line: 285
DefaultLoadEventListener.onLoad(LoadEvent, LoadEventListener$LoadType) line: 152
SessionImpl.fireLoad(LoadEvent, LoadEventListener$LoadType) line: 1090
SessionImpl.internalLoad(String, Serializable, boolean, boolean) line: 1038
ManyToOneType(EntityType).resolveIdentifier(Serializable, SessionImplementor) line: 630
ManyToOneType(EntityType).resolve(Object, SessionImplementor, Object) line: 438
EmbeddedComponentType(ComponentType).resolve(Object, SessionImplementor, Object) line: 617
CascadeEntityLoader(Loader).extractKeysFromResultSet(Loadable[], QueryParameters, ResultSet, SessionImplementor, EntityKey[], LockMode[], List) line: 722
CascadeEntityLoader(Loader).getRowFromResultSet(ResultSet, SessionImplementor, QueryParameters, LockMode[], EntityKey, List, EntityKey[], boolean) line: 606
CascadeEntityLoader(Loader).doQuery(SessionImplementor, QueryParameters, boolean) line: 829
CascadeEntityLoader(Loader).doQueryAndInitializeNonLazyCollections(SessionImplementor, QueryParameters, boolean) line: 274
CascadeEntityLoader(Loader).loadEntity(SessionImplementor, Object, Type, Object, String, Serializable, EntityPersister, LockOptions) line: 2037
CascadeEntityLoader(AbstractEntityLoader).load(SessionImplementor, Object, Object, Serializable, LockOptions) line: 86
CascadeEntityLoader(AbstractEntityLoader).load(Serializable, Object, SessionImplementor, LockOptions) line: 76
SingleTableEntityPersister(AbstractEntityPersister).load(Serializable, Object, LockOptions, SessionImplementor) line: 3293
DefaultLoadEventListener.loadFromDatasource(LoadEvent, EntityPersister, EntityKey, LoadEventListener$LoadType) line: 496
DefaultLoadEventListener.doLoad(LoadEvent, EntityPersister, EntityKey, LoadEventListener$LoadType) line: 477
DefaultLoadEventListener.load(LoadEvent, EntityPersister, EntityKey, LoadEventListener$LoadType) line: 227
DefaultLoadEventListener.proxyOrLoad(LoadEvent, EntityPersister, EntityKey, LoadEventListener$LoadType) line: 285
DefaultLoadEventListener.onLoad(LoadEvent, LoadEventListener$LoadType) line: 152
SessionImpl.fireLoad(LoadEvent, LoadEventListener$LoadType) line: 1090
SessionImpl.internalLoad(String, Serializable, boolean, boolean) line: 1038
ManyToOneType(EntityType).resolveIdentifier(Serializable, SessionImplementor) line: 630
ManyToOneType(EntityType).resolve(Object, SessionImplementor, Object) line: 438
EmbeddedComponentType(ComponentType).resolve(Object, SessionImplementor, Object) line: 617
CascadeEntityLoader(Loader).extractKeysFromResultSet(Loadable[], QueryParameters, ResultSet, SessionImplementor, EntityKey[], LockMode[], List) line: 722
CascadeEntityLoader(Loader).getRowFromResultSet(ResultSet, SessionImplementor, QueryParameters, LockMode[], EntityKey, List, EntityKey[], boolean) line: 606
CascadeEntityLoader(Loader).doQuery(SessionImplementor, QueryParameters, boolean) line: 829
CascadeEntityLoader(Loader).doQueryAndInitializeNonLazyCollections(SessionImplementor, QueryParameters, boolean) line: 274
CascadeEntityLoader(Loader).loadEntity(SessionImplementor, Object, Type, Object, String, Serializable, EntityPersister, LockOptions) line: 2037
CascadeEntityLoader(AbstractEntityLoader).load(SessionImplementor, Object, Object, Serializable, LockOptions) line: 86
CascadeEntityLoader(AbstractEntityLoader).load(Serializable, Object, SessionImplementor, LockOptions) line: 76
SingleTableEntityPersister(AbstractEntityPersister).load(Serializable, Object, LockOptions, SessionImplementor) line: 3293
DefaultRefreshEventListener.onRefresh(RefreshEvent, Map) line: 151
DefaultRefreshEventListener.onRefresh(RefreshEvent) line: 62
SessionImpl.fireRefresh(RefreshEvent) line: 1118
SessionImpl.refresh(Object) line: 1098
EntityManagerImpl(AbstractEntityManagerImpl).refresh(Object, LockModeType, Map<String,Object>) line: 903
EntityManagerImpl(AbstractEntityManagerImpl).refresh(Object) line: 878

...

1 个答案:

答案 0 :(得分:3)

我从@OneToMany声明中删除了CascadeType.REFRESH属性。现在Hibernate重新读取@OneToMany集合,但不会尝试重新读取其成员。

看起来像是一种解决方法,但这正是我需要的。