Hibernate version: 3.3.1
Hi,
I was looking at the code for JPAValidateListener to see how it cached ClassValidators in a servlet environment. However, it seems to use an unsynchronized static map to cache them. How does this class avoid thread safety issues when creating/accessing the ClassValidators?
Any general recommendations for caching ClassValidators in a Spring/Hibernate/Servlet environment?
Here is the code for reference:
Code:
public class JPAValidateListener {
//No need for weakReference if the event listener is loaded by the same CL than
//the entities, but in a shared env this is not the case
//TODO check that this can be hot redeployable
private static final Map<Class, WeakReference<ClassValidator>> validators;
private static final ClassValidator<JPAValidateListener> NO_VALIDATOR;
static {
validators = new WeakHashMap<Class, WeakReference<ClassValidator>>();
NO_VALIDATOR = new ClassValidator<JPAValidateListener>( JPAValidateListener.class);
}
//keep hardref at the instance level
private final Set<ClassValidator> currentValidators = new HashSet<ClassValidator>();
@PrePersist
@PreUpdate
@SuppressWarnings( "unchecked" )
public void onChange(Object object) {
if (object == null) return;
Class entity = object.getClass();
WeakReference<ClassValidator> weakValidator = validators.get(entity);
ClassValidator validator = weakValidator != null ? weakValidator.get() : null;
if ( validator == null ) {
//initialize
//TODO reuse the same reflection manager?
validator = new ClassValidator(entity);
if ( ! validator.hasValidationRules() ) {
validator = NO_VALIDATOR;
}
validators.put( entity, new WeakReference<ClassValidator>(validator) );
currentValidators.add( validator );
}
if ( validator != NO_VALIDATOR ) {
validator.assertValid( object );
}
}
}
Thank you for your help!