【问题标题】:Loading Blaze-persistence entity view by JPA specification通过 JPA 规范加载 Blaze-persistence 实体视图
【发布时间】:2021-09-22 16:28:52
【问题描述】:

我为某个实体准备了一个“香草”JPA 规范。我还为同一实体准备了 Blase-persistence 实体视图界面。如何使用准备好的 JPA 规范加载该实体视图?

编辑: 目前,我正在使用这个规范:

CriteriaBuilder cb = entityManager.getCriteriaBuilder();
CriteriaQuery<EntityClass> query = cb.createQuery(EntityClass.class);
Root<EntityClass> root = query.from(EntityClass.class);
query.where(specification.toPredicate(root, query, cb));
EntityGraph graph = entityManager.getEntityGraph(entityGraphName);
TypedQuery<EntityClass> = entityManager.createQuery(query)
.setHint("javax.persistence.loadgraph", graph);
List<EntityClass> result = typedQuery.getResultList();

之后,我将实体列表转换为投影列表。 现在,我正在尝试在类似的场景中用实体视图替换实体图和投影,实体视图的类作为参数。

【问题讨论】:

  • 你的意思是 Spring Data JPA 规范吗?
  • 我的意思是,接口 org.springframework.data.jpa.domain.Specification 的实现。甚至在 Spring Data 存储库之外使用它。

标签: java jpa spring-data blaze-persistence


【解决方案1】:

您可以将CriteriaQuery 或实际上的BlazeCriteriaQuery 转换为quickstart 中概述的Blaze-Persistence CriteriaBuilder,大致如下所示:

// This is a subclass of the JPA CriteriaBuilder interface
BlazeCriteriaBuilder cb = BlazeCriteria.get(criteriaBuilderFactory);
// A subclass of the JPA CriteriaQuery interface
BlazeCriteriaQuery<EntityClass> query = cb.createQuery(EntityClass.class);
Root<EntityClass> root = query.from(EntityClass.class);
query.where(specification.toPredicate(root, query, cb));
// Finally, transform the BlazeCriteriaQuery to the Blaze-Persistence Core CriteriaBuilder
CriteriaBuilder<EntityClass> builder = query.createCriteriaBuilder(entityManager);

此时,您可以将EntityViewSetting 应用于该查询并检索entity-view quickstart 中所述的结果:

CriteriaBuilder<MyEntityView> viewBuilder = evm.applySetting(EntityViewSetting.create(MyEntityView.class), builder );
List<MyEntityView> myViews = viewBuilder .getResultList();

【讨论】:

  • 这几乎可以工作,但在调用此方法时出现错误:InvalidDataAccessApiUsageException:不支持的强制转换类型:java.time.LocalDate。我应该包含一些兼容性 maven 依赖项来支持 java.time 类吗?
  • 能否分享一下引发此异常的相关代码部分?也许不需要演员阵容?
  • 相关部分是规范的一部分。它是 case 子句(基本上,如果不为空,则取一个日期,如果是 - 取另一个),稍后用于比较(因此它必须是日期,否则抛出异常)。通过转换为 java.SQL.Date 找到了解决方法(以及转换用于比较的值),但还有另一个问题。当结果 sql 代码仅由 JPA+Hibernate 生成时,此转换不会出现在那里,case 子句按原样工作。但是使用 blaze-persistence,case 子句在生成的 sql 代码中被强制转换为日期(cast - case expression - as date),这会减慢执行速度
  • 更新:在 JPA + Hibernate 和 blaze-persistence 方法中,通常使用 java.sql.Date 类会导致不必要的强制转换。所以,我需要转换为 LocalDate 以在规范中表达大小写。
  • 我可以尝试对此进行修复,但现在您可能必须使用cb.function("treat_localdate", LocalDate.class, arg) 作为解决方法,这将省略 SQL 中的强制转换。
猜你喜欢
  • 1970-01-01
  • 2012-01-25
  • 1970-01-01
  • 2016-03-14
  • 2015-07-31
  • 2021-12-06
  • 1970-01-01
  • 2023-01-31
  • 2018-11-01
相关资源
最近更新 更多