简体   繁体   English

如何使用 JPA Criteria Builder 指定子句原因语句

[英]How can you specify clause cause statements with JPA Criteria Builder

I need to specify the AS OF SYSTEM TIME follower_read_timestamp() clause cause statement from CockroachDB to my query using Criteria Builder.我需要使用 Criteria Builder 将 CockroachDB 的AS OF SYSTEM TIME follower_read_timestamp()子句原因语句指定为我的查询。 I need to use Criteria Builder since my queries are dynamically constructed and have a lot of different optional predicates based upon user input.我需要使用 Criteria Builder,因为我的查询是动态构建的,并且有很多基于用户输入的不同可选谓词。 I need to specify the clause cause statement because I am running into some transaction issues and have been advised to add it by support.我需要指定子句原因声明,因为我遇到了一些交易问题,并且建议支持人员添加它。 I also just generally want to know how/if to add clauses like this since I've had to do it other times as well.hibernate我也只是想知道如何/是否添加这样的子句,因为我也不得不在其他时候这样做。hibernate

Here is the AS OF SYSTEM TIME CockroachDB clause cause statement docs https://www.cockroachlabs.com/docs/v22.2/as-of-system-time这是AS OF SYSTEM TIME CockroachDB 子句原因声明文档https://www.cockroachlabs.com/docs/v22.2/as-of-system-time

Here is an example of what my Criteria Builder code looks like -- it's actually much more complicated but I simplified it for this question.这是我的 Criteria Builder 代码的示例——它实际上要复杂得多,但我针对这个问题对其进行了简化。

// Get criteria builder
CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder();

// Create criteria query and root
CriteriaQuery<StorageEntity> criteriaQuery = criteriaBuilder.createQuery(StorageEntity.class);
Root<StorageEntity> root = criteriaQuery.from(StorageEntity.class);

List<Predicate> predicates = new ArrayList<>();

if (CollectionUtils.isNotEmpty(ids)) {
  predicates.add(criteriaBuilder.<List<UUID>> in(root.get("id")).value(ids));
}

/**
A lot of other dynamic predicates are added here which is why I'm using criteria builder
*/

if (CollectionUtils.isNotEmpty(otherIds)) {
  predicates.add(criteriaBuilder.<List<UUID>> in(root.get("otherIds")).value(otherIds));
}

// Get criteria query with filter predicates
criteriaQuery = criteriaQuery.where(predicates.toArray(new Predicate[] {}));

// Create query
TypedQuery<StorageEntity> query = entityManager.createQuery(criteriaQuery);

/**
Ideally here I would be able to add `AS OF SYSTEM TIME <timestamp>` clause cause statement
*/

// Execute query and get results
List<StorageEntity> storageEntities = query.getResultList();

ps I'm using jakarta.persistence:jakarta.persistence-api:2.2.3 pulled in as a transitive dependency by org.springframework.boot:spring-boot-starter-data-jpa:2.7.7 ps 我正在使用jakarta.persistence:jakarta.persistence-api:2.2.3作为传递依赖被org.springframework.boot:spring-boot-starter-data-jpa:2.7.7

I haven't tested this (came here from the cockroachdb tag), but judging from docs, JPA doesn't automatically quote identifiers containing spaces.我没有对此进行测试(来自 cockroachdb 标签),但从文档来看,JPA 不会自动引用包含空格的标识符。 Given that, since the clause goes at the end of the FROM clause in a table, you could probably just use a class annotated with鉴于此,由于该子句位于表中 FROM 子句的末尾,您可能只使用带注释的 class

Table(name = "actual_table_name AS OF SYSTEM TIME follower_read_timestamp()")

Instead of the normal table name annotation whenever you want the clause.每当您需要该子句时,而不是普通的表名注释。 Since AS OF SYSTEM TIME only works in top-level queries, this should generate valid SQL as long as this is the last table name referenced in the FROM clause.由于AS OF SYSTEM TIME仅适用于顶级查询,因此只要这是 FROM 子句中引用的最后一个表名,它就应该生成有效的 SQL。

If that doesn't work in your actual query, you might be stuck building the query, extracting the raw SQL, adding in the clause through string manipulation, and then executing it natively.如果这在您的实际查询中不起作用,您可能无法构建查询,提取原始 SQL,通过字符串操作添加子句,然后在本机执行它。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM