@SuppressWarnings("unchecked") private void index( Object entity, Session session, InstanceInitializer sessionInitializer, ConversionContext conversionContext) throws InterruptedException { // abort if the thread has been interrupted while not in wait(), I/O or similar which themselves // would have // raised the InterruptedException if (Thread.currentThread().isInterrupted()) { throw new InterruptedException(); } Serializable id = session.getIdentifier(entity); Class<?> clazz = HibernateHelper.getClass(entity); EntityIndexBinding entityIndexBinding = entityIndexBindings.get(clazz); if (entityIndexBinding == null) { // it might be possible to receive not-indexes subclasses of the currently indexed type; // being not-indexed, we skip them. // FIXME for improved performance: avoid loading them in an early phase. return; } EntityIndexingInterceptor interceptor = entityIndexBinding.getEntityIndexingInterceptor(); if (interceptor != null) { IndexingOverride onAdd = interceptor.onAdd(entity); switch (onAdd) { case REMOVE: case SKIP: return; } // default: continue indexing this instance } DocumentBuilderIndexedEntity docBuilder = entityIndexBinding.getDocumentBuilder(); TwoWayFieldBridge idBridge = docBuilder.getIdBridge(); conversionContext.pushProperty(docBuilder.getIdKeywordName()); String idInString = null; try { idInString = conversionContext.setClass(clazz).twoWayConversionContext(idBridge).objectToString(id); } finally { conversionContext.popProperty(); } // depending on the complexity of the object graph going to be indexed it's possible // that we hit the database several times during work construction. AddLuceneWork addWork = docBuilder.createAddWork( tenantId, clazz, entity, id, idInString, sessionInitializer, conversionContext); backend.enqueueAsyncWork(addWork); }
private Work interceptWork(EntityIndexBinding indexBindingForEntity, Work work) { if (indexBindingForEntity == null) { return work; } EntityIndexingInterceptor interceptor = indexBindingForEntity.getEntityIndexingInterceptor(); if (interceptor == null) { return work; } IndexingOverride operation; switch (work.getType()) { case ADD: operation = interceptor.onAdd(work.getEntity()); break; case UPDATE: operation = interceptor.onUpdate(work.getEntity()); break; case DELETE: operation = interceptor.onDelete(work.getEntity()); break; case COLLECTION: operation = interceptor.onCollectionUpdate(work.getEntity()); break; case PURGE: case PURGE_ALL: case INDEX: case DELETE_BY_QUERY: operation = IndexingOverride.APPLY_DEFAULT; break; default: throw new AssertionFailure("Unknown work type: " + work.getType()); } Work result = work; Class<?> entityClass = work.getEntityClass(); switch (operation) { case APPLY_DEFAULT: break; case SKIP: result = null; log.forceSkipIndexOperationViaInterception(entityClass, work.getType()); break; case UPDATE: result = new Work(work.getTenantIdentifier(), work.getEntity(), work.getId(), WorkType.UPDATE); log.forceUpdateOnIndexOperationViaInterception(entityClass, work.getType()); break; case REMOVE: // This works because other Work constructors are never used from WorkType ADD, UPDATE, // REMOVE, COLLECTION // TODO should we force isIdentifierRollback to false if the operation is not a delete? result = new Work( work.getTenantIdentifier(), work.getEntity(), work.getId(), WorkType.DELETE, work.isIdentifierWasRolledBack()); log.forceRemoveOnIndexOperationViaInterception(entityClass, work.getType()); break; default: throw new AssertionFailure("Unknown action type: " + operation); } return result; }