-->
These old forums are deprecated now and set to read-only. We are waiting for you on our new forums!
More modern, Discourse-based and with GitHub/Google/Twitter authentication built-in.

All times are UTC - 5 hours [ DST ]



Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 5 posts ] 
Author Message
 Post subject: flush causes lazy collections with cascade to initialize
PostPosted: Sat Dec 03, 2005 2:38 am 
Beginner
Beginner

Joined: Wed Jun 15, 2005 1:28 pm
Posts: 39
Location: United States
Hibernate version: EJB RC3 patch 1

Problem: I have watched in my debugger the cascade mechanism triggering the initialization of a series of previously uninitialized (lazy) collections when no persist, merge or remove call was made (only read operations). This does not look like intended behavior, and causes much unnecessary database I/O.

Here are the highlights of the call graph within Hibernate during the problem:

Code:
EJBTxPolicy.endTransaction()
TransactionImpl.commit()
EntityManagerImpl.flush()
SessionImpl.flush()
EJB3FlushEventListener.cascadeOnFlush()
Cascade.cascade()
Cascade.cascadeCollection()
CascadingAction.getCascadableChildrenIterator()
PersistentSet.iterator()
SessionImpl.initializeCollection()
// ...Hibernate procceeds to issue the undesired select statement...
OneToManyPersister.initialize()



Here is the application context (four levels of parent/child) in simplified, understandable terms:

I have an entity Country with a OneToMany collection States.
The State entity has a OneToMany collection Counties.
The County entity has a OneToMany collection Townships.
The Township entity has a OneToMany collection Cities.

All of the collections are FetchType.LAZY, and CascadeType MERGE, PERSIST, REMOVE.

The presentation layer already has a list of Country objects. When the States collection is needed, I pass the selected detatched Country object to a DAO function, listStates(Country). The DAO is a Stateless bean.

Code:

Set<State> listStates(Country country) {
     em.refresh(country);  //reattach detached country
     Set<Section> set = country.listStates();  //get the list of sections
     int size = set.size();  //get the number of states (causes lazy init)
     return set  //return the states for this country
}



Inside the Country class:

Code:

private Set<State> getStates(){
     return states;
}

@Transient
public Set<State> listStates() {
     return getStates();
}



After the DAO function returns, Hibernate automatically ends the transaction started by the EntityManager when the DAO function was called, beginning the call graph above.

Hibernate then proceeds to initialize the County collection for each State, and the Township collection for each County.

This is a lot of database activity, an is undesirable for performance reasons.

All that was requested of the DAO tier was the State collection, which resulted in only one SELECT.

After returning the State collection successfully, the framework proceeds to read in the rest of the unneeded data in the name of Cascade functionality, and delays the results of the call to the client until finished.

I would appreciate any insights into this issue from the community. Thank you.


Top
 Profile  
 
 Post subject:
PostPosted: Sat Dec 03, 2005 6:30 am 
Beginner
Beginner

Joined: Fri Oct 07, 2005 5:35 am
Posts: 38
Location: France
Your problem looks not so far as mine (look at last post in the thread). Whe using collection with CascadeType to (Persist, Remove, ...), flush is not efficient.

http://forum.hibernate.org/viewtopic.php?t=948850

A JIRA issue is open for that:
http://opensource2.atlassian.com/projects/hibernate/browse/HHH-1207


Top
 Profile  
 
 Post subject:
PostPosted: Sat Dec 03, 2005 6:30 am 
Beginner
Beginner

Joined: Fri Oct 07, 2005 5:35 am
Posts: 38
Location: France
Your problem looks not so far as mine (look at last post in the thread). Whe using collection with CascadeType to (Persist, Remove, ...), flush is not efficient.

http://forum.hibernate.org/viewtopic.php?t=948850

A JIRA issue is open for that:
http://opensource2.atlassian.com/projects/hibernate/browse/HHH-1207


Top
 Profile  
 
 Post subject:
PostPosted: Sat Dec 03, 2005 2:08 pm 
Beginner
Beginner

Joined: Wed Jun 15, 2005 1:28 pm
Posts: 39
Location: United States
The main issue identified in this post is that during flush the Cascade functionality triggers lazy initialization of collections which were not previously initialized in the business application.

I believe that hibernate should protect against causing lazy initialization of a collection from within the framework routines. An uninitialized collection does not contain any objects...

Are you seeing this behavior in your application? It sounds to me like you have found the application searching through objects in memory which are not dirty. If I understand your issue correctly, you have no additional database I/O being added to your application, correct?

In my case, the flush process is very time consuming because the framework loads the entire object graph from the database who are descendents of the objects I have loaded. We're talking a lot more than milliseconds here.


Top
 Profile  
 
 Post subject:
PostPosted: Sun Dec 04, 2005 6:22 am 
Hibernate Team
Hibernate Team

Joined: Sun Sep 14, 2003 3:54 am
Posts: 7256
Location: Paris, France
busitech,
Check that http://opensource.atlassian.com/project ... wse/EJB-52
I've fixed your pb for 2+ level deep in CVS.

_________________
Emmanuel


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 5 posts ] 

All times are UTC - 5 hours [ DST ]


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.