I have a legacy database which I'm trying to access using Hibernate 3.
In this database I have two entities: A and B, and third entity C which represent a relation between A and B. The C entity holds also some additional information about the relation, so it cannot be coded just as @ManyToMany.
The C entity refers the A and B entities using @Id and @ManyToOne annotations. The A and B entities list the C entity as sets using @OneToMany annotation.
The underlying database may change, so I try to use the Hibernate refresh() procedure to re-read data for the A entity from the database.
This causes and endless recursion loop: A->C->A->C... which results in stack overflow.
It seems this refresh() procedure tries to refresh every reference, including the lazy ones, with unlimited depth. This is not that is really necessary for me, it would suffice, if I could make a "shallow" refresh and reset all @OneToMany sets back to the "uninitialized" state.
So my question is:
How can I avoid this endless recursion,
or
how can I just "reset" an entity back to "uninitialized" state.
Below is a part of stack trace produced with 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
...
I removed the CascadeType.REFRESH attribute from @OneToMany declaration. Now Hibernate re-reads the @OneToMany collection, but does not try to re-read its members.
Looks like a workaround, but it is what I need.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With