public IdentifierConsumerDocumentProducer( ProducerConsumerQueue<List<Serializable>> fromIdentifierListToEntities, MassIndexerProgressMonitor monitor, SessionFactory sessionFactory, CountDownLatch producerEndSignal, CacheMode cacheMode, Class<?> type, ExtendedSearchIntegrator searchFactory, String idName, BatchBackend backend, ErrorHandler errorHandler, Integer transactionTimeout, String tenantId) { this.source = fromIdentifierListToEntities; this.monitor = monitor; this.sessionFactory = sessionFactory; this.cacheMode = cacheMode; this.type = type; this.idName = idName; this.backend = backend; this.errorHandler = errorHandler; this.producerEndSignal = producerEndSignal; this.entityIndexBindings = searchFactory.getIndexBindings(); this.transactionTimeout = transactionTimeout; this.tenantId = tenantId; this.transactionManager = ((SessionFactoryImplementor) sessionFactory) .getServiceRegistry() .getService(JtaPlatform.class) .retrieveTransactionManager(); log.trace("created"); }
protected MassIndexerImpl( SearchIntegrator searchIntegrator, SessionFactoryImplementor sessionFactory, Class<?>... entities) { this.extendedIntegrator = searchIntegrator.unwrap(ExtendedSearchIntegrator.class); this.sessionFactory = sessionFactory; rootEntities = toRootEntities(extendedIntegrator, entities); if (extendedIntegrator.isJMXEnabled()) { monitor = new JMXRegistrar.IndexingProgressMonitor(); } else { monitor = new SimpleIndexingProgressMonitor(); } }
private IndexManager[] getIndexManagersAfterReopening() { // build a new independent SessionFactory to verify that the shards are available at restart Configuration config = new Configuration(); config.setProperty( "hibernate.search.Animal.sharding_strategy", DynamicShardingTest.AnimalShardIdentifierProvider.class.getName()); // use filesystem based directory provider to be able to assert against index config.setProperty("hibernate.search.default.directory_provider", "filesystem"); Path sub = getBaseIndexDir(); config.setProperty("hibernate.search.default.indexBase", sub.toAbsolutePath().toString()); config.addAnnotatedClass(Animal.class); try (SessionFactory newSessionFactory = config.buildSessionFactory()) { try (FullTextSession fullTextSession = Search.getFullTextSession(newSessionFactory.openSession())) { ExtendedSearchIntegrator integrator = fullTextSession.getSearchFactory().unwrap(ExtendedSearchIntegrator.class); return integrator.getIndexBindings().get(Animal.class).getIndexManagers(); } } }
@Override public void performWork(Work work, TransactionContext transactionContext) { final Class<?> entityType = instanceInitializer.getClassFromWork(work); EntityIndexBinding indexBindingForEntity = factory.getIndexBinding(entityType); if (indexBindingForEntity == null && factory.getDocumentBuilderContainedEntity(entityType) == null) { throw new SearchException( "Unable to perform work. Entity Class is not @Indexed nor hosts @ContainedIn: " + entityType); } work = interceptWork(indexBindingForEntity, work); if (work == null) { // nothing to do return; } if (transactionContext.isTransactionInProgress()) { final Object transactionIdentifier = transactionContext.getTransactionIdentifier(); WorkQueueSynchronization txSync = synchronizationPerTransaction.get(transactionIdentifier); if (txSync == null || txSync.isConsumed()) { txSync = createTransactionWorkQueueSynchronization(transactionIdentifier); transactionContext.registerSynchronization(txSync); synchronizationPerTransaction.put(transactionIdentifier, txSync); } txSync.add(work); } else { if (transactionExpected) { // this is a workaround: isTransactionInProgress should return "true" // for correct configurations. log.pushedChangesOutOfTransaction(); } WorkQueue queue = new WorkQueue(factory); queueingProcessor.add(work, queue); queueingProcessor.prepareWorks(queue); queueingProcessor.performWorks(queue); } }
/** * From the set of classes a new set is built containing all indexed subclasses, but removing then * all subtypes of indexed entities. * * @param selection * @return a new set of entities */ private static Set<Class<?>> toRootEntities( ExtendedSearchIntegrator extendedIntegrator, Class<?>... selection) { Set<Class<?>> entities = new HashSet<Class<?>>(); // first build the "entities" set containing all indexed subtypes of "selection". for (Class<?> entityType : selection) { Set<Class<?>> targetedClasses = extendedIntegrator.getIndexedTypesPolymorphic(new Class[] {entityType}); if (targetedClasses.isEmpty()) { String msg = entityType.getName() + " is not an indexed entity or a subclass of an indexed entity"; throw new IllegalArgumentException(msg); } entities.addAll(targetedClasses); } Set<Class<?>> cleaned = new HashSet<Class<?>>(); Set<Class<?>> toRemove = new HashSet<Class<?>>(); // now remove all repeated types to avoid duplicate loading by polymorphic query loading for (Class<?> type : entities) { boolean typeIsOk = true; for (Class<?> existing : cleaned) { if (existing.isAssignableFrom(type)) { typeIsOk = false; break; } if (type.isAssignableFrom(existing)) { toRemove.add(existing); } } if (typeIsOk) { cleaned.add(type); } } cleaned.removeAll(toRemove); log.debugf("Targets for indexing job: %s", cleaned); return cleaned; }
@SuppressWarnings({CompilerWarnings.UNCHECKED}) private void buildEntityMetadatas() throws Exception { SessionFactoryImpl sessionFactory = ((SessionFactoryImpl) this.entityManagerFactory.getSessionFactory()); Class<?> entityBindingMappedClass; Class<? extends SdcctEntity> entityMappedClass; String entityName, entityPropName, entityPropFieldName; EntityMetadata entityMetadata; Map<String, PropertyMetadata> entityPropMetadatas; IndexedTypeDescriptor indexedEntityDesc; Method entityPropGetterMethod; boolean entityIndexed, entityPropIndexed; PropertyDescriptor indexedEntityPropDesc; PropertyMetadata entityPropMetadata; BidiMap<Integer, String> entityPropOrder; String[] entityPropOrderNames; for (PersistentClass entityBinding : metadata.getEntityBindings()) { if (((entityBindingMappedClass = entityBinding.getMappedClass()) == null) || !SdcctEntity.class.isAssignableFrom(entityBindingMappedClass)) { continue; } entityPropMetadatas = (entityMetadata = new EntityMetadataImpl( (entityName = entityBinding.getEntityName()), (entityIndexed = (indexedEntityDesc = searchIntegrator.getIndexedTypeDescriptor( (entityMappedClass = ((Class<? extends SdcctEntity>) entityBindingMappedClass)))) .isIndexed()), entityMappedClass, entityBinding.getTable().getName())) .getProperties(); this.entityMetadatas.put( ((Class<? extends SdcctEntity>) entityMappedClass.getInterfaces()[0]), entityMetadata); for (Property entityProp : IteratorUtils.asIterable( IteratorUtils.chainedIterator( ((Iterator<Property>) entityBinding.getRootClass().getPropertyIterator()), ((Iterator<Property>) entityBinding.getPropertyIterator())))) { entityPropName = entityProp.getName(); entityPropGetterMethod = entityProp.getGetter(entityMappedClass).getMethod(); if (entityProp.getColumnSpan() == 0) { continue; } entityPropIndexed = (entityIndexed && entityPropGetterMethod.isAnnotationPresent(Fields.class) && ((indexedEntityPropDesc = indexedEntityDesc.getProperty(entityPropName)) != null) && !indexedEntityPropDesc.isId()); entityPropMetadatas.put( entityPropName, (entityPropMetadata = new PropertyMetadataImpl( entityPropName, entityPropIndexed, ((Column) entityProp.getColumnIterator().next()).getName(), entityProp.getType()))); if (entityPropIndexed) { for (Field entityPropFieldAnno : entityPropGetterMethod.getAnnotation(Fields.class).value()) { if (entityPropFieldAnno.analyze() == Analyze.NO) { continue; } entityPropFieldName = entityPropFieldAnno.name(); switch (entityPropFieldAnno.analyzer().definition()) { case DbAnalyzerNames.EDGE_NGRAM: entityPropMetadata.setEdgeNgramFieldName(entityPropFieldName); break; case DbAnalyzerNames.LOWERCASE: entityPropMetadata.setLowercaseFieldName(entityPropFieldName); break; case DbAnalyzerNames.NGRAM: entityPropMetadata.setNgramFieldName(entityPropFieldName); break; case DbAnalyzerNames.PHONETIC: entityPropMetadata.setPhoneticFieldName(entityPropFieldName); break; } } } } entityMetadata.setIdProperty( entityPropMetadatas.get(entityBinding.getIdentifierProperty().getName())); entityPropOrder = entityMetadata.getPropertyOrder(); entityPropOrderNames = sessionFactory.getEntityPersister(entityName).getPropertyNames(); for (int a = 0; a < entityPropOrderNames.length; a++) { entityPropOrder.put(a, entityPropOrderNames[a]); } } LOGGER.debug( String.format( "Processed metadata for %d entities: [%s]", this.entityMetadatas.size(), this.entityMetadatas .values() .stream() .map(NamedBean::getName) .collect(Collectors.joining(", ")))); }