休眠搜索:从查询中获取参数化结果,而无需检查警告

时间:2018-11-01 11:34:51

标签: java hibernate hibernate-search

是否可以在Hibernate Search中从查询中获取参数化结果而没有未经检查的警告?

在Hibernate ORM(5.3.7.Final)中,可以编写以下代码而没有任何未经检查的警告:

List<Entity> result = session.createQuery("from Entity", Entity.class).list();

但是在Hibernate Search(5.10.4.Final)中,即使在创建和执行查询期间两次指定Entity.class,我目前也无法获得参数化结果:

QueryBuilder queryBuilder = fullTextSession
                .getSearchFactory()
                .buildQueryBuilder()
                .forEntity(Entity.class)
                .get();
org.apache.lucene.search.Query luceneQuery = queryBuilder
                .keyword()
                .onField("field")
                .matching("value")
                .createQuery();
Query query = fullTextSession.createFullTextQuery(luceneQuery, Entity.class);
List result = query.list();

我当然可以这样写:

Query<Entity> query = fullTextSession.createFullTextQuery(luceneQuery, Entity.class);
List<Entity> result = query.list();

但这是未经检查的作业。

或者我可以写

List<Entity> parametrisedResult = (List<Entity>) result;

但是这里我有一个未经检查的演员表。

由于Hibernate ORM具有这种可能性,因此我认为在Hibernate Search中也可以编写没有未经检查的警告的代码。

谢谢。

1 个答案:

答案 0 :(得分:1)

否,当前无法实例化类型安全的FullTextQuery(原因如下)。推荐的方法是这种方法,它可以与Search 5.10以及旧版本(5.7之前的版本)配合使用:

QueryBuilder queryBuilder = fullTextSession
                .getSearchFactory()
                .buildQueryBuilder()
                .forEntity(Entity.class)
                .get();
org.apache.lucene.search.Query luceneQuery = queryBuilder
                .keyword()
                .onField("field")
                .matching("value")
                .createQuery();

FullTextQuery query = fullTextSession.createFullTextQuery(luceneQuery, Entity.class);
List<Entity> result = (List<Entity>) query.list();

为什么?

根据ORM标准,创建类型安全查询的功能相当新:JPA 2.1(ORM 5.2)附带了该功能。在此之前,list()方法用于在ORM中返回原始List(无泛型类型参数),在Hibernate Search查询中也是如此。

休眠搜索并没有更改以遵循ORM,但是:FullTextQuery扩展了org.hibernate.query.Query作为原始类型,没有任何参数。原因是,FullTextQuery对象上有一些变量可以更改返回的对象,从而可以更改返回的类型(特别是setProjection方法)。因此,即使我们在构建查询时可以返回FullTextQuery<Entity>,这也会产生误导,因为在某些情况下,您最终可能会获得实际上返回结果的FullTextQuery<Entity>类型List<Object[]>

我们探索了一些方法来解决这种情况,但是找不到能够保证类型安全并允许保持向后兼容性的解决方案。因此,我们已经放弃了Hibernate Search 5的功能。

如果您想知道,ORM不会遇到相同的问题,因为您指定了创建查询时要返回的确切类型,并且以后无法更改。

在Hibernate Search的下一个专业版本6中,将解决该问题。新的查询构建API要求在创建查询之前指定 查询是返回托管实体还是返回索引投影。 Hibernate Search 6尚不稳定,尚未准备好投入生产,但是如果您好奇,可以找到一个示例hereasEntity调用告诉Search应该返回什么类型)。