Interceptor Global threadsafe

Ola pessoal,
alguem tem algum exemplo ou orientacoes referente a um interceptor global threadsafe. Sei que interceptor session scoped eh threadsafe, porem o meu interceptor e global.
Ref.: http://java.dzone.com/articles/using-a-hibernate-interceptor-

public class AuditLogInterceptor extends EmptyInterceptor { private Session session; private Long userId; private Set inserts = new HashSet(); private Set updates = new HashSet(); public void setSession(Session session) { this.session=session; } public void setUserId(Long userId) { this.userId=userId; } public boolean onSave(Object entity, Serializable id, Object[] state, String[] propertyNames, Type[] types) throws CallbackException { if (entity instanceof Auditable) inserts.add(entity); return false; } public boolean onFlushDirty(Object entity, Serializable id, Object[] currentState, Object[] previousState, String[] propertyNames, Type[] types) throws CallbackException { if (entity instanceof Auditable) updates.add(entity); return false; } public void postFlush(Iterator iterator) throws CallbackException { try { for (Iterator it = inserts.iterator(); it.hasNext();) { Auditable entity = (Auditable) it.next(); AuditLog.logEvent("create",entity,userId,session.connection()); } for (Iterator it = updates.iterator(); it.hasNext();) { Auditable entity = (Auditable) it.next(); AuditLog.logEvent("update",entity,userId,session.connection()); } } finally { inserts.clear(); updates.clear(); } } }
[]s
Fabio

Pessoal,
a quem interessar, criei um mapa com o id da thread e os seus respectivos objetos para auditoria.

[code]public class HibernateInterceptor extends EmptyInterceptor {

private static final Logger LOG = Logger.getLogger(HibernateInterceptor.class);

private static final long serialVersionUID = 1L;
public Map<Long,HashSet<AuditoriaEntity>> inserts = new HashMap<Long,HashSet<AuditoriaEntity>>();
public Map<Long,HashSet<AuditoriaEntity>> updates = new HashMap<Long,HashSet<AuditoriaEntity>>();
public Map<Long,HashSet<AuditoriaEntity>> deletes = new HashMap<Long,HashSet<AuditoriaEntity>>();

@Override
public void onDelete(Object entity, Serializable id, Object[] state,
		String[] propertyNames, Type[] types) {
	if(isObjetoAuditoria(entity)){
		AuditoriaEntity entidade = (AuditoriaEntity)entity;
		entidade.setPropertyNames(propertyNames);
		entidade.setTypes(types);
		adicionaItemMapa(deletes, (AuditoriaEntity)entity);
	}
}

@Override
public void postFlush(Iterator entities) {
	try{
		if(hasItens(inserts)){
			SessionRestFilter.auditoria.get().addAllObjetoAuditoria(getModificacaoObjeto(getSet(inserts), Constantes.EVENTO_INCLUIR));
		}
		if(hasItens(updates)){
			SessionRestFilter.auditoria.get().addAllObjetoAuditoria(getModificacaoObjeto(getSet(updates), Constantes.EVENTO_EXCLUIR));
		}
		if(hasItens(deletes)){
			SessionRestFilter.auditoria.get().addAllObjetoAuditoria(getModificacaoObjeto(getSet(deletes), Constantes.EVENTO_ALTERAR));
		}
	}catch(Exception e){
		LOG.info("Erro interceptor", e);
	}finally{
		limpaItensMapas();
	}
}

private boolean hasItens(Map<Long, HashSet<AuditoriaEntity>> mapa) {
	if(getSet(mapa) == null){
		return false;
	}
	return !getSet(mapa).isEmpty();
}

private Set<ObjetoLOG> getModificacaoObjeto(Set<AuditoriaEntity> objetosAlterados, String evento){
	Set<ObjetoLOG> objetos = new HashSet<ObjetoLOG>();
	AuditoriaEntity entity;
	ObjetoLOG objeto;
	PropdObjetoLog propriedadeObjeto;
	for(Iterator<AuditoriaEntity> it = objetosAlterados.iterator(); it.hasNext();){
		entity = it.next();
		objeto = new ObjetoLOG(entity.getClass().getSimpleName());
		propriedadeObjeto = new PropdObjetoLog();
		String nomePropriedade;
		for (int i =0; i < entity.getPropertyNames().length; i++){
			if(isTipoPermitido(entity.getTypes()[i])){
				propriedadeObjeto = new PropdObjetoLog();
				nomePropriedade = entity.getPropertyNames()[i];
				propriedadeObjeto.setNomePropdObjeto(nomePropriedade);
				if(Constantes.EVENTO_INCLUIR.als(evento)){
					propriedadeObjeto.setDescricaoValObjetoNovo(BeanUtils.executaMetodo("get" + nomePropriedade.substring(0,1).toUpperCase() + nomePropriedade.substring(1, nomePropriedade.length()), entity, null).toString());
					objeto.addPropriedadeObjetoAuditoria(propriedadeObjeto);
				}else if(Constantes.EVENTO_EXCLUIR.als(evento)){
					propriedadeObjeto.setDescricaoValObjetoAntigo(BeanUtils.executaMetodo("get" + nomePropriedade.substring(0,1).toUpperCase() + nomePropriedade.substring(1, nomePropriedade.length()), entity, null).toString());
					objeto.addPropriedadeObjetoAuditoria(propriedadeObjeto);
				}else{
					if(isAtualizacaoValor(entity.getCurrentState()[i], entity.getPreviousState()[i]) ){
						propriedadeObjeto.setDescricaoValObjetoNovo(entity.getCurrentState()[i].toString());
						propriedadeObjeto.setDescricaoValObjetoAntigo(entity.getPreviousState()[i].toString());
						objeto.addPropriedadeObjetoAuditoria(propriedadeObjeto);
					}
				}
			}
        }
		objetos.add(objeto);
	}
	return objetos;
}

@Override
public boolean onSave(Object entity, Serializable id, Object[] state,
		String[] propertyNames, Type[] types) {
	if(isObjetoAuditoria(entity)){
		AuditoriaEntity entidade = (AuditoriaEntity)entity;
		entidade.setPropertyNames(propertyNames);
		entidade.setTypes(types);
		adicionaItemMapa(inserts, (AuditoriaEntity)entity);
	}
	return false;
}

@Override
public boolean onFlushDirty(Object entity, Serializable id,
		Object[] currentState, Object[] previousState,
		String[] propertyNames, Type[] types) {
	
	if(isObjetoAuditoria(entity)){
		AuditoriaEntity entidade = (AuditoriaEntity)entity;
		entidade.setPropertyNames(propertyNames);
		entidade.setTypes(types);
		entidade.setCurrentState(currentState);
		entidade.setPreviousState(previousState);
		adicionaItemMapa(updates, (AuditoriaEntity)entity);
	}
	return false;
}

private HashSet<AuditoriaEntity> getSet(Map<Long, HashSet<AuditoriaEntity>> mapa) {
	Long idThread = Thread.currentThread().getId();
	return mapa.get(idThread);
}

private void adicionaItemMapa(Map<Long, HashSet<AuditoriaEntity>> mapa,AuditoriaEntity entity) {
	Long idThread = Thread.currentThread().getId();
	if(mapa.get(idThread) == null){
		mapa.put(idThread, new HashSet<AuditoriaEntity>());
	}
	mapa.get(idThread).add(entity);
}

private void limpaItensMapas() {
	Long idThread = Thread.currentThread().getId();
	inserts.remove(idThread);
	updates.remove(idThread);
	deletes.remove(idThread);
}

private boolean isTipoPermitido(Type type) {
	return type instanceof StringType || type instanceof IntegerType || type instanceof DoubleType || type instanceof BigDecimal || type instanceof DateType;
}

private boolean isAtualizacaoValor(Object valorNovo, Object valorAntigo) {
	if(valorAntigo == null){
		return true;
	}
	return !valorNovo.toString().equals(valorAntigo.toString());
}

private boolean isObjetoAuditoria(Object entity) {		
	return entity instanceof AuditoriaEntity;
}

}[/code]