我正在尝试将hibernate搜索集成到我的项目中。我的模型已编制索引,但由于某些原因,我的搜索查询不会返回任何结果。我一直试图解决这个问题几个小时,但我做的一切似乎都没有用。
域对象:
@Entity
@Table(name = "roles")
@Indexed
public class Role implements GrantedAuthority {
private static final long serialVersionUID = 8227887773948216849L;
@Id @GeneratedValue
@DocumentId
private Long ID;
@Column(name = "authority", nullable = false)
@Field(index = Index.TOKENIZED, store = Store.YES)
private String authority;
@ManyToMany
@JoinTable(name = "user_roles", joinColumns = { @JoinColumn(name = "role_id") }, inverseJoinColumns = { @JoinColumn(name = "username") })
@ContainedIn
private List<User> users;
...
}
DAO:
public abstract class GenericPersistenceDao<T> implements IGenericDao<T> {
@PersistenceContext
private EntityManager entityManager;
...
@Override
public FullTextEntityManager getSearchManager() {
return Search.getFullTextEntityManager(entityManager);
}
}
服务:
@Service(value = "roleService")
public class RoleServiceImpl implements RoleService {
@Autowired
private RoleDao roleDAO;
...
@Override
@SuppressWarnings("unchecked")
public List<Role> searchRoles(String keyword) throws ParseException {
FullTextEntityManager manager = roleDAO.getSearchManager();
TermQuery tquery = new TermQuery(new Term("authority", keyword));
FullTextQuery query = manager.createFullTextQuery(tquery, Role.class);
return query.getResultList();
}
}
测试:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = { "classpath:applicationContext.xml" })
@Transactional
public class TestRoleService extends Assert {
@Autowired
private RoleService roleService;
@Test
public void testSearchRoles() {
roleService.saveRole(/* role with authority="test" */);
List<Role> roles = roleService.searchRoles("test");
assertEquals(1, roles.size()); // returns 0
}
}
配置
<persistence-unit name="hibernatePersistence" transaction-type="RESOURCE_LOCAL">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<properties>
<property name="hibernate.search.default.directory_provider" value="org.hibernate.search.store.FSDirectoryProvider" />
<property name="hibernate.search.default.indexBase" value="indexes" />
</properties>
</persistence-unit>
<!-- Entity manager -->
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalEntityManagerFactoryBean">
<property name="persistenceUnitName" value="hibernatePersistence" />
</bean>
<!-- Transaction manager -->
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory" />
</bean>
<!-- Enable the configuration of transaction behavior based on annotations -->
<tx:annotation-driven transaction-manager="transactionManager" />
<context:component-scan base-package="org.myproject" />
数据库实际上填充了与该权限字段值匹配的角色。实体经理有效,因为我的所有常规CRUD测试都成功。意思是错误完全是与hibernate搜索(3.1.1.GA)相关的,但哪里出错?
答案 0 :(得分:2)
从理论上说这一切都有效但可能存在一些问题:
答案 1 :(得分:1)
最后管理让它工作..显然对象没有自动索引..或至少没有提交。我的实现现在看起来如下:
public List<Role> searchRoles(String keyword) {
// Index domain object (works)
EntityManager manager = factory.createEntityManager();
FullTextEntityManager ftManager = Search.getFullTextEntityManager(manager);
ftManager.getTransaction().begin();
List<Role> roles = ftManager.createQuery("select e from " + Role.class.getName() + " e").getResultList();
for (Role role : roles) {
ftManager.index(role);
}
ftManager.getTransaction().commit();
// Retrieve element from search (works)
TermQuery tquery = new TermQuery(new Term("authority", keyword));
FullTextQuery query = ftManager.createFullTextQuery(tquery, Role.class);
return query.getResultList();
}
通过执行index和getTransactionCommit函数,索引正确存储在我的索引文件夹中。然而,这个实现非常不自然,因为我为文本搜索创建了另一个实体管理器。是否有一种“更清洁”的方法来使用@Transactional注释
来索引(和提交)记录答案 2 :(得分:1)
最后通过附加以下属性解决了我的问题: hibernate.search.worker.batch_size = 1
我现在不仅可以正确查询,而且每当我持久保存域对象时索引也会自动更新。我现在唯一的问题是通过我的import.sql插入的数据不会自动编入索引。是否有某种“魔术”hibernate.search属性可用于此问题,还是应该手动索引它们?