Hibernate Search:在没有未经检查的警告的情况下从查询中获取参数化结果

Hibernate Search: Get parametrised result from query without unchecked warnings

在 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中也可以编写没有unchecked warnings的代码。

提前致谢。

不,目前无法实例化类型安全的 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() 方法用于 return ORM 中的原始 List(没有泛型类型参数),在 Hibernate 搜索查询中也是如此。

Hibernate Search 没有更改为遵循 ORM,但是:FullTextQueryorg.hibernate.query.Query 扩展为原始类型,没有任何参数。原因是,FullTextQuery 对象上有允许更改 returned 对象的更改器,因此 returned 类型(特别是 setProjection 方法) .因此,即使我们 可以 return 一个 FullTextQuery<Entity> 当你构建一个查询时,这也会产生误导,因为在某些情况下你可能会得到一个 FullTextQuery<Entity> 实际上是 return 类型 List<Object[]> 的结果。

我们探索了一些解决这种情况的选项,但找不到既能保证类型安全又能保持向后兼容性的解决方案。所以我们已经放弃了 Hibernate Search 5。

如果您想知道,ORM 不会有同样的问题,因为您在创建查询时指定了您希望查询的确切类型 return,并且之后无法更改它。

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