[hibernate-issues] [Hibernate-JIRA] Created: (HHH-3967) Great performance improvement for CascadingAction.PERSIST_ON_FLUSH action !!

Guenther Demetz (JIRA) noreply at atlassian.com
Wed Jun 17 05:40:33 EDT 2009


Great performance improvement for CascadingAction.PERSIST_ON_FLUSH action !!
----------------------------------------------------------------------------

                 Key: HHH-3967
                 URL: http://opensource.atlassian.com/projects/hibernate/browse/HHH-3967
             Project: Hibernate Core
          Issue Type: Improvement
          Components: core
    Affects Versions: 3.3.1
         Environment: 3.3.1 GA , SQLServer
            Reporter: Guenther Demetz


Sometimes large stateful transactions are unavoidable and especially when having several large persistent collections in dirty state,
flushing becomes gradually more cpu intensive and slowly.
Analizing several stacktraces I detected that the thread most time is executing at the same point in reflection , 
see here a typical stacktrace:

java.lang.Class.isAssignableFrom(Native Method)
sun.reflect.UnsafeFieldAccessorImpl.ensureObj(UnsafeFieldAccessorImpl.java:36)
...
java.lang.reflect.Field.get(Field.java:358)
DirectPropertyAccessor$DirectGetter.get(DirectPropertyAccessor.java:55)
PojoEntityTuplizer(AbstractEntityTuplizer).getPropertyValue(Object, int) line: 300	
SingleTableEntityPersister(AbstractEntityPersister).getPropertyValue(Object, int, EntityMode) line: 3609	
Cascade.cascade(EntityPersister, Object, Object) line: 172	
...


Making further investigations, I saw that:
- CascadingAction.PERSIST_ON_FLUSH requires NoCascadeChecking 
- for all kind of properties the noCascade implementation is called
- regarding noCascade implementation checks only properties of type Entity !

public static final CascadingAction PERSIST_ON_FLUSH = new CascadingAction() {
		...
		public void noCascade(EventSource session, Object child, Object parent,	EntityPersister persister, int propertyIndex) {
			...
			Type type = persister.getPropertyTypes()[propertyIndex];
			if ( type.isEntityType() ) {
				... check and throw eventually a TransientObjectException
			}
		}

Thus most property values are retrieved by reflection in vain as they are not of type entity.
With following code addition in org.hibernate.engine.Cascade.java 
I was able do avoid most reflection method calls without affecting the behaviour:

org.hibernate.engine.Cascade.java
...
public void cascade(final EntityPersister persister, final Object parent, final Object anything) throws HibernateException {
...
       else if ( action.requiresNoCascadeChecking() ) {      

// Line:162	
// begin Improvement
				    if (action == CascadingAction.PERSIST_ON_FLUSH) {
				           Type type = persister.getPropertyTypes()[i];
			                   if ( !type.isEntityType() ) {
			                       // Remark: goes only well as long PERSIST_ON_FLUSH noCascade implementation checks only entities
			                       continue;
			                   }
				    }
// end Improvement
				    
					action.noCascade(
							eventSource,
							persister.getPropertyValue( parent, i, entityMode ),
							parent,
							persister,
							i
					);
                                      ...

best regards
Guenther D.

-- 
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators: http://opensource.atlassian.com/projects/hibernate/secure/Administrators.jspa
-
For more information on JIRA, see: http://www.atlassian.com/software/jira

        



More information about the hibernate-issues mailing list