Hibernate version: 3.2.5GA
Hi all,
I am using hibernate in a 'dirty' way : it is only used because of its mappings (used in our main application). I generate test data to CSV files.
Appearently, Hibernate is my bottleneck (CSV files are saved to a RamDisk ;o) so it can't be it; no changes in my statistics hereunder between Ramdisk and normal HDD):
[500 groups per transaction; 5.000 groups of objects generated)
- no save : 1.000 groups of objects are generated per second
- + getHibernateTemplate.save() : 30 per second :o(
- + getHibernateTemplate.persist() : 43 per second
I already managed to avoid useless select queries by :
- setting all 'not-null="true"' as 'not-null="false"' in the mapping files (copies of originals)
- bypass validation and save 'draft' objects (see
http://www.sleberknight.com/blog/sleberkn/date/200710)
My class :
Code:
public class NoHibernateValidationEventListener extends ValidateEventListener {
static final long serialVersionUID = 0L;
private static ThreadLocal<Boolean> shouldValidateThreadLocal = new ThreadLocal<Boolean>() {
@Override
protected Boolean initialValue() {
return Boolean.FALSE;
}
};
/**
* Constructor.
*/
public NoHibernateValidationEventListener() {
// do nothing
super();
}
/**
* Perform validation before insert, <code>unless</code> {@link #turnValidationOff()} has been called for the
* currently executing thread.
*
* @param event the PreInsertEvent
* @return Return true if the operation should be vetoed
*/
@Override
public boolean onPreInsert(final PreInsertEvent event) {
return isCurrentlyValidating() && super.onPreInsert(event);
}
/**
* Perform validation before update, <code>unless</code> {@link #turnValidationOff()} has been called for the
* currently executing thread.
*
* @param event the PreUpdateEvent
* @return Return true if the operation should be vetoed
*/
@Override
public boolean onPreUpdate(final PreUpdateEvent event) {
return isCurrentlyValidating() && super.onPreUpdate(event);
}
/** Call this method to explicitly turn validation on for the currently executing thread. */
public static void turnValidationOn() {
NoHibernateValidationEventListener.shouldValidateThreadLocal.set(Boolean.TRUE);
}
/** Call this method to bypass validation for the currently executing thread. */
public static void turnValidationOff() {
NoHibernateValidationEventListener.shouldValidateThreadLocal.set(Boolean.FALSE);
}
/** @return <code>true</code> if we need to validate for the current thread */
public static Boolean isCurrentlyValidating() {
return NoHibernateValidationEventListener.shouldValidateThreadLocal.get();
}
}
My Spring context for that connection :
Code:
...
...
<bean id="hibernatePropertiesHxtt" class="org.springframework.beans.factory.config.PropertiesFactoryBean">
<property name="properties">
<props>
<prop key="hibernate.dialect">com.hxtt.support.hibernate.HxttTextDialect</prop>
<prop key="hibernate.show_sql">false</prop>
<prop key="hibernate.c3p0.minPoolSize">1</prop>
<prop key="hibernate.c3p0.maxPoolSize">50</prop>
<prop key="hibernate.c3p0.timeout">600</prop>
<prop key="hibernate.c3p0.testConnectionOnCheckout">false</prop>
<prop key="hibernate.current_session_context_class">org.hibernate.context.ManagedSessionContext</prop>
<prop key="hibernate.generate_statistics">false</prop>
<!-- used to bypass select queries befor insert;
Used in conjunction with NoHibernateValidationEventListener class (bean sessionFactoryHxtt) -->
<prop key="hibernate.validator.autoregister_listeners">false</prop>
</props>
</property>
</bean>
...
...
<bean id="sessionFactoryHxtt" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSourceHxtt" />
<property name="mappingResources" ref="mappingResourcesHxtt" />
<property name="hibernateProperties" ref="hibernatePropertiesHxtt" />
<!-- No Hibernate operation will be validated -->
<property name="eventListeners">
<map>
<entry key="pre-update">
<bean class="com.biblio.NoHibernateValidationEventListener"/>
</entry>
<entry key="pre-insert">
<bean class="com.biblio.NoHibernateValidationEventListener"/>
</entry>
</map>
</property>
</bean>
...
...
OK, I know, this is too trivial for Hibernate. I don't intend to get 1.000 per second with Hibernate, but at least 55 (or more :o) ).
What seems strange is that I see my HDD-light blink during the generation, what shouldn't (it all happens in memory).
Is there a way to avoid those HDD accesses? I think this is all I need...
I cannot figure if this is Windows swapping (I always have at least 500Mb free memory while processing) or purely Hibernate.
Does someone have a clue?
Many Thanks![/code]