2

My requirement Is to each index per tenant , I do already have hibernate configured as MultiTenant , I need to index the database per tenant to different Index. I have seen to dynamicSharding Strategy.. But requirement is dynamic. it can have n number of shards without being any pre information about each tenant existence. Even My Indexer should work in a way that. Whenever it finds the hibernate request fetching the index it should index that tenant first and then search over it.

How i can do it..??

Can anybody give me some example. Please don't give hibernate doc links... or even Jboss doc links for hibernate search.

Satyam Soni
  • 103
  • 1
  • 7
  • So you are saying that you've seen and read the dynamic sharding documentation of Hibernate Search. Did you have a look at ShardIdentifierProvider and the example given in the documentation. Dynamic sharing allows you to create new shards on the fly, why does it not fit your use case? – Hardy Dec 30 '14 at 20:20
  • I read it. It fits it.. Bt my requirement is i can also dynamic shards the each tenant respectively too. – Satyam Soni Dec 31 '14 at 08:08
  • Hi Hardy, I studied the hibernate search, but the problem i m facing currently is when i try with dynamic sharding strategy. on firing search query. But it doesn't indexes the data By Code is as Follows FullTextSession fullTextSession = Search.getFullTextSession(getCurrentSession()); fullTextSession.createIndexer().startAndWait(); – Satyam Soni Jan 01 '15 at 13:16
  • Sorry, I have a hard time making sense of your comment above. Maybe you could update the question with the code you have and the concrete problem you are facing now? – Hardy Jan 01 '15 at 19:29
  • The actual problem i am facing is as follows : I am using ThreadLocal to get tenantIndentifier. Now i do manage the indexing on the basis that for first request of any new tenant i do get datasource and session factory of that tenant based on threadLocal and index that table into lucene. I am using massIndexer for indexing the tenant database. But the indexing works on new thread so i dont get any reference of tenantIdentifier from my threadLocal as it is from new thread invoked for indexing. So how to resolve this issue. Though i use sync indexing option. – Satyam Soni Jan 02 '15 at 14:09
  • com.poc.provider.TenantFSDirectoryProvider /home/ezdi-domain.lan/smsoni/lucene com.poc.provider.MultiTenantShardingStrategy sync – Satyam Soni Jan 02 '15 at 14:14
  • Hi Hardy. Me waiting for your answer... – Satyam Soni Jan 06 '15 at 13:41
  • 1
    I have a similar problem. The MassIndexer doesn't seems working properly for MultiTenant with dynamic Shard Identifier, Though the Hibernate i am using supports via Multi Tenancy MultiTenantConnectionProvider. – Charvee Shah Jan 06 '15 at 14:41
  • 1
    I think using the mass indexer in this case will indeed not work. As you say, you won't be able to get the tenant id via a ThreadLocal. You could try indexing via FullTextSession#index. Have a look at this example http://docs.jboss.org/hibernate/stable/search/reference/en-US/html_single/#search-batchindex-flushtoindexes – Hardy Jan 07 '15 at 14:19
  • Will this also work for auto update of data. I am currently having MultiTenant sessionFactory configured for my application. will this also auto update data in respective tenant Index automatically. ?? i mean to say that.. for first time indexing i can use this strategy. but my doubt is regarding the auto update indexing feature of hibernate search shall also work for multiTenant. again you need to note that i am using ThreadLocal to get tenantIdentifier in hibernate orm. – Satyam Soni Jan 07 '15 at 14:52
  • @Hardy waiting for your answers. Please reply. – Satyam Soni Jan 13 '15 at 07:18

1 Answers1

0

To index over a specific tenant you should add the properties of hibernate search of section Entitymanager on your application context, as follow as an example:

<bean depends-on="dataSource" id="entityManagerFactory"
    class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
    <property name="jpaVendorAdapter">
        <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
            <property name="databasePlatform" value="org.hibernate.dialect.SQLServerDialect" />
            <property name="generateDdl" value="true"></property>
            <property name="showSql" value="true" />
        </bean>
    </property>
    <property name="packagesToScan" value="xxx.xxxx..xxx." />
    <property name="persistenceUnitName" value="xxxxxx" />
    <property name="dataSource" ref="dataSource" />
    <property name="jpaProperties">
        <props>
            <prop key="hibernate.dialect">org.hibernate.dialect.SQLServerDialect</prop>
            <prop key="hibernate.search.default.directory_provider">filesystem</prop>
            <prop key="hibernate.search.default.indexBase">C:\xxxxx\indexes</prop>

        </props>
    </property>
</bean> 

Now you have to use org.hibernate.Session to identify your tenant to perform a search to a specific tenant as follow:

EntityManager manager = managerFactory.createEntityManager();

SessionImpl i = (SessionImpl) manager.getDelegate();
SessionFactory session = i.getSessionFactory();

Session s = session.withOptions().tenantIdentifier(xxxxx).openSession();

FullTextSession fullTextSession = org.hibernate.search.Search.getFullTextSession(s);
return fullTextSession; 

This way each search will use a specifc tenant that you provide, but for me seems that you have another problem that is how to get the tenant, in my case I use the url to identify the tenant, if you have anyway that a user choose te tenant to use, get that information in a static variable to use when necessary.

Ethaan
  • 11,291
  • 5
  • 35
  • 45
DAM
  • 25
  • 6