Hibernate refresh () вызывает переполнение стека из-за рекурсии встроенного компонента - PullRequest
2 голосов
/ 02 декабря 2011

У меня есть устаревшая база данных, к которой я пытаюсь получить доступ с помощью Hibernate 3.

В этой базе данных у меня есть две сущности: A и B , и третья сущность C , которые представляют отношение между A и B . Сущность C также содержит некоторую дополнительную информацию об отношении, поэтому ее нельзя кодировать так же, как @ ManyToMany.

Сущность C ссылается на сущности A и B , используя аннотации @Id и @ManyToOne. Сущности A и B перечисляют сущность C как наборы, используя аннотацию @OneToMany.

Базовая база данных может измениться, поэтому я пытаюсь использовать процедуру Hibernate refresh () для повторного чтения данных для объекта A из базы данных.

Это вызывает и бесконечный цикл рекурсии: A -> C -> A -> 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 Ответ

3 голосов
/ 06 декабря 2011

Я удалил атрибут CascadeType.REFRESH из объявления @OneToMany.Теперь Hibernate перечитывает коллекцию @OneToMany, но не пытается перечитать ее элементы.

Выглядит как обходной путь, но это то, что мне нужно.

...