我使用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;
}
}
答案 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();