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,但是:FullTextQuery
将 org.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 还不稳定,尚未准备好投入生产,但如果您好奇,可以找到一个示例 here(asEntity
调用告诉 Search return 类型应该是什么).
在 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,但是:FullTextQuery
将 org.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 还不稳定,尚未准备好投入生产,但如果您好奇,可以找到一个示例 here(asEntity
调用告诉 Search return 类型应该是什么).