]
Gail Badner updated HHH-3967:
-----------------------------
Fix Version/s: 4.1.0
Great performance improvement for CascadingAction.PERSIST_ON_FLUSH
action !!
----------------------------------------------------------------------------
Key: HHH-3967
URL:
http://opensource.atlassian.com/projects/hibernate/browse/HHH-3967
Project: Hibernate ORM
Issue Type: Improvement
Components: core
Affects Versions: 3.3.1
Environment: 3.3.1 GA , SQLServer
Reporter: Guenther Demetz
Assignee: Gail Badner
Fix For: 4.1.0
Attachments: Cascade.java
Original Estimate: 0.5h
Remaining Estimate: 0.5h
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.
For more information on JIRA, see: