Hibernate Search返回空结果列表

时间:2014-11-10 14:20:00

标签: spring hibernate jpa lucene hibernate-search

我使用Hibernate Search编写基于Spring的Web应用程序进行全文搜索。但是当我尝试搜索实体时,hibernate搜索返回空列表作为结果。我还使用JPA存储库来处理DB。我在服务类中使用@transactional注释。

这是我的spring-config.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans  xmlns="http://www.springframework.org/schema/beans"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns:context="http://www.springframework.org/schema/context"
        xmlns:jpa="http://www.springframework.org/schema/data/jpa" xmlns:tx="http://www.springframework.org/schema/tx"
        xmlns:security="http://www.springframework.org/schema/security"
        xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context-3.1.xsd
        http://www.springframework.org/schema/data/jpa
        http://www.springframework.org/schema/data/jpa/spring-jpa.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd http://www.springframework.org/schema/security
        http://www.springframework.org/schema/security/spring-security-3.2.xsd">

    <context:component-scan base-package="project"/>

    <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
        <property name="entityManagerFactory" ref="entityManagerFactory"/>
    </bean>

    <jpa:repositories base-package="project" transaction-manager-ref="transactionManager"
                      entity-manager-factory-ref="entityManagerFactory"/>

    <bean id="entityManagerFactory"
          class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
        <property name="packagesToScan" value="project"/>
        <property name="dataSource" ref="postgresDataSource"/>
        <property name="validationMode" value="NONE"/>
        <property name="jpaProperties">
            <props>
                <prop key="hibernate.show_sql">true</prop>
                <prop key="hibernate.hbm2ddl.auto">update</prop>
                <prop key="hibernate.dialect">org.hibernate.dialect.PostgreSQL81Dialect</prop>
            </props>
        </property>
        <property name="persistenceProvider">
            <bean class="org.hibernate.jpa.HibernatePersistenceProvider"/>
        </property>
    </bean>


    <bean id="postgresDataSource" class="org.apache.commons.dbcp.BasicDataSource">
        <property name="driverClassName" value="org.postgresql.Driver"/>
        <property name="url" value="jdbc:postgresql://localhost:5432/LabourExchange"/>
        <property name="username" value="postgres"/>
        <property name="password" value="123456"/>
    </bean>

    <tx:annotation-driven transaction-manager="transactionManager"/>


    <!--security config-->
    <security:http auto-config="true" use-expressions="true">
        <security:intercept-url pattern="/pages/**" access="isAuthenticated()"/>
        <security:form-login
                login-page="/auth/login.jsf"
                default-target-url="/pages/home.jsf"
                authentication-failure-url="/auth/login.jsf?status=error"/>
        <security:logout logout-success-url="/hello.jsf"/>
    </security:http>

    <security:authentication-manager>
        <security:authentication-provider user-service-ref="UserDetailsService">
        </security:authentication-provider>
    </security:authentication-manager>
</beans>

我的实体

@Entity
@Table(name = "resumes")
@Indexed
public class Resume {
    @Id @Column(name = "id") @GeneratedValue(strategy = GenerationType.IDENTITY)
    private long id;

    @Column(name = "title")
    @Field( analyze= Analyze.NO, name = "title")
    @NotBlank @Size(min = 10, max = 100)
    private String title;

    @Column(name = "text")
    @Field(analyze=Analyze.NO, name = "text")
    @NotBlank @Size(min = 50, max = 10000)
    private String text;

    @Column(name = "salary")
    @NotNull
    private double salary;

    @ManyToOne(optional = false)
    @JoinColumn(name = "creator_id")
    private User creator;

    public User getCreator() {
        return creator;
    }

    public void setCreator(User creator) {
        this.creator = creator;
    }

    public long getId() {
        return id;
    }

    public void setId(long id) {
        this.id = id;
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public String getText() {
        return text;
    }

    public void setText(String text) {
        this.text = text;
    }

    public double getSalary() {
        return salary;
    }

    public void setSalary(double salary) {
        this.salary = salary;
    }
}

SearchBean

@ManagedBean
@RequestScoped
public class SearchBean implements Serializable {

    public List<Resume> findResumes(String query) {
        EntityManager em = ContextLoader.getCurrentWebApplicationContext().getBean(EntityManager.class);
        FullTextEntityManager fullTextEntityManager =
                org.hibernate.search.jpa.Search.getFullTextEntityManager(em);

        QueryBuilder qb = fullTextEntityManager.getSearchFactory()
                .buildQueryBuilder().forEntity(Resume.class).get();
        org.apache.lucene.search.Query luceneQuery = qb
                .keyword()
                .onField("text")
                .matching("zzzzz")
                .createQuery();

        javax.persistence.Query jpaQuery =
                fullTextEntityManager.createFullTextQuery(luceneQuery, Resume.class);
        // execute search
        List result = jpaQuery.getResultList();

        return result;
    }
}

3 个答案:

答案 0 :(得分:0)

您似乎没有在hibernate属性下的spring xml文件中提供indexBase位置和FSDirectoryProvider

请指明这两者,在我的情况下,我是以下面的方式做的:

        <prop key="hibernate.search.default.directory_provider">
            org.hibernate.search.store.impl.FSDirectoryProvider
        </prop>
        <prop key="hibernate.search.default.indexBase">
            C:\yourLocation\lucene
        </prop>

答案 1 :(得分:0)

我在调用wildcard()

后忘记了致电keyword()功能

答案 2 :(得分:0)

忘记构建索引时遇到类似的问题。

解决方案是在Hibernate Session:

fullTextSession.createIndexer().startAndWait();

在JPA Entitymanager:

fullTextEntityManager.createIndexer().startAndWait();