是否可以在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中也可以编写没有未经检查的警告的代码。
谢谢。
答案 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尚不稳定,尚未准备好投入生产,但是如果您好奇,可以找到一个示例here(asEntity
调用告诉Search应该返回什么类型)。>