Hibernate Search + Spring + JPA + 2 уеб приложения - правилна конфигурация

Търсих дълго и упорито и не мога да намеря окончателен отговор.

Имам 2 уеб приложения, работещи на едно копие на tomcat: /server и /ROOT

Конфигурирах Hibernate Search, конфигуриран за един от моите обекти, т.е. Products.

Тези обекти се редактират/добавят на /server и се търсят от крайни потребители на уебсайта /ROOT

по време на нормални операции всичко работи както трябва, редактирането на обекти на сървъра ще доведе до отразяване на тези промени при извършване на търсене в предния край.

въпреки това, след неопределено време или последователност от събития, индексът вече не се актуализира.

ето конфигурацията за /server

<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
    <property name="dataSource" ref="jpaDataSource" />
    <property name="packagesToScan" value="com.foo" />
    <property name="jpaVendorAdapter">
            <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
                    <property name="generateDdl" value="true" />
                    <property name="showSql" value="true" />
            </bean>
    </property>
    <property name="jpaPropertyMap" ref="jpaPropertyMap" />
</bean>

<util:map id="jpaPropertyMap">
    <entry key="hibernate.search.default.directory_provider" value="filesystem" />
    <entry key="hibernate.search.default.indexBase" value="${lucene.index.folder}" />
</util:map>

и ето конфигурацията за /ROOT

<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
    <property name="dataSource" ref="dataSource" />
    <property name="packagesToScan" value="com.foo" />
    <property name="jpaVendorAdapter">
            <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
                    <property name="generateDdl" value="true" />
                    <property name="showSql" value="true" />
            </bean>
    </property>
    <property name="jpaPropertyMap" ref="jpaPropertyMap" />
</bean>

<util:map id="jpaPropertyMap">
    <entry key="hibernate.search.default.directory_provider" value="filesystem" />
    <entry key="hibernate.search.default.indexBase" value="${lucene.index.folder}" />
</util:map>

По същество идентични.

и ето как е конфигуриран моят Entity чрез AspectJ ITD

privileged aspect Product_Search {

declare @type: Product: @Indexed;

declare @method :public Long Product.getId() : @DocumentId;
declare @method :public String Product.getTitle() : @Field(index=Index.YES, analyze=Analyze.YES, store=Store.NO);
declare @method :public String Product.getSubTitle() : @Field(index=Index.YES, analyze=Analyze.YES, store=Store.NO);
declare @method :public String Product.getAlternativeTitle() : @Field(index=Index.YES, analyze=Analyze.YES, store=Store.NO);
declare @method :public String Product.getIdentifier() : @Field(index=Index.YES, analyze=Analyze.YES, store=Store.NO);
declare @method :public String Product.getPrimaryCreators() : @Field(index=Index.YES, analyze=Analyze.YES, store=Store.NO);
declare @method :public String Product.getSecondaryCreators() : @Field(index=Index.YES, analyze=Analyze.YES, store=Store.NO);
declare @method :public String Product.getSubjectArea() : @Field(index=Index.YES, analyze=Analyze.YES, store=Store.NO);
declare @method :public String Product.getPublisher() : @Field(index=Index.YES, analyze=Analyze.NO, store=Store.NO);
declare @method :public String Product.getTags() : @Field(index=Index.YES, analyze=Analyze.YES, store=Store.NO);

При по-нататъшно търсене открих главния/подчинения DirectoryProvider

/server

    <util:map id="jpaPropertyMap">
    <entry key="hibernate.search.default.directory_provider" value="filesystem-master" />
    <entry key="hibernate.search.default.indexBase" value="${lucene.index.folder}/primary" />
    <entry key="hibernate.search.default.sourceBase" value="${lucene.index.folder}/master" />
    <entry key="hibernate.search.default.refresh" value="120" />
</util:map>

/ROOT

    <util:map id="jpaPropertyMap">
    <entry key="hibernate.search.default.directory_provider" value="filesystem-slave" />
    <entry key="hibernate.search.default.sourceBase" value="${lucene.index.folder}/master" />
    <entry key="hibernate.search.default.indexBase" value="${lucene.index.folder}/slave" />
    <entry key="hibernate.search.default.refresh" value="300" />
</util:map>

Това изглежда работеше до по-рано днес, когато по някаква причина моят индекс се „нулира“ и съдържаше само елементите, които бяха част от последния импортиран продукт. Имам предвид, че моята DB има 10 000 елемента, но ако направих query = new MatchAllDocsQuery();, получих само 15 (размера на последното импортиране)

Това наистина ме подлудява.

В момента трябва да сваля уебсайтовете, да изтрия индекса, да стартирам сървъра, да индексирам отново с помощта на FullTextEntityManager fullTextEntityManager = Search.getFullTextEntityManager(entityManager()); fullTextEntityManager.createIndexer().startAndWait();

Уведомете ме, ако имате нужда от повече информация

Благодаря


person kabal    schedule 18.03.2013    source източник


Отговори (2)


Ако промените идват само чрез приложението сървър и винаги искате да стартирате сървър и ROOT на една и съща машина, няма нужда от настройка главен/подчинен. Една проста настройка на файловата система трябва да свърши работа, но искате да се уверите, че в приложението ROOT _hibernate.search.indexing_strategy = manual_ е указано. По този начин актуализациите на индекса ще се извършват само когато API за изрично индексиране се използва в приложението ROOT.

включи ли записването? Има ли нещо в дневниците. Мисля, че първата стъпка е да се опитате да възпроизведете проблема по надежден начин. Ако просто кажете, че първоначално работи, но след това внезапно започне да се проваля, това затруднява намирането на причината. Опитахте ли с някои автоматизирани тестове за натоварване?

person Hardy    schedule 19.03.2013
comment
Току-що се случи отново в производството. Ще превключа нивото на журнала за търсене в хибернация на DEBUG за следващите няколко дни. - person kabal; 19.03.2013
comment
Ако има 90% вероятност в близко бъдеще, че ще редактираме и в приложението ROOT, тогава препоръчва ли се настройката master/slave? Главен/подчинен трябва ли да се изпълнява с JMS? - person kabal; 19.03.2013
comment
Докато двете приложения са на една и съща машина, можете да използвате директорията на файловата система. Lucene има свой собствен механизъм за заключване на индекса, така че индексът не може да бъде повреден (за това се отнася този изключителен флаг в другия отговор). Master/Slave е необходим, когато имате няколко машини. Можете също да използвате JGroups за etup, но JMS е препоръчителният начин. - person Hardy; 19.03.2013

Една идея - може би трябва да преминете към неизключителен режим (вижте за exclusive_index_use)

person Michail Nikolaev    schedule 18.03.2013