【问题标题】:JPA Criteria api with oracle12c JSON_VALUE function带有 oracle12c JSON_VALUE 函数的 JPA Criteria api
【发布时间】:2017-02-15 02:29:45
【问题描述】:

我正在尝试使用 JSON_VALUE 函数()的克里特标准 API 查询是 Oracle12c:

select * from orderswhere (JSON_VALUE(duty, '$.department') in ( ? , ? , ? ,? , ? , ? , ?));

型号:

@Entity
@Table(name = "orders")
@EntityListeners(AuditingEntityListener.class)
public class Trade implements Serializable {
     @Convert(converter = JpaConverterJson.class)
     private Map<String, Object> duty;
     .....
}

private Specification<InvoicePurchase> reportFormToSpec(Map<String, Object> 
    params) {
        return (root, query, cb) -> {
             List<Predicate> predicates = new ArrayList<>();
       if (!StringUtils.isEmpty(params.get("department"))) {
            Predicate predicate = cb.like(cb.function("json_value", String.class,
                    root.get("duty"),
                    cb.literal("$.department"))
                    , params.get("department"));
            predicates.add(predicate);
        }
            return query.where(predicates.toArray(new Predicate[predicates.size()])).getRestriction();
        };

    }

但出现异常:o.h.engine.jdbc.spi.SqlExceptionHelper: ORA-40454:path expression not a literal

我在网上搜索了很长时间。但是没有用。请帮助或尝试提供一些想法如何实现这一目标。

错误代码:

   2017-11-23 12:26:55.271  WARN 11972 --- [nio-8080-exec-1] o.h.engine.jdbc.spi.SqlExceptionHelper   : SQL Error: 40454, SQLState: 99999
   2017-11-23 12:26:55.271 ERROR 11972 --- [nio-8080-exec-1] o.h.engine.jdbc.spi.SqlExceptionHelper   : ORA-40454: path expression not a literal

【问题讨论】:

  • 错误消息:2017-02-15 14:22:13.210 WARN 23176 --- [nio-8080-exec-7] o.h.engine.jdbc.spi.SqlExceptionHelper:SQL 错误:40454,SQLState :99999 2017-02-15 14:22:13.210 错误 23176 --- [nio-8080-exec-7] o.h.engine.jdbc.spi.SqlExceptionHelper:ORA-40454:路径表达式不是文字

标签: spring hibernate jpa spring-boot spring-data-jpa


【解决方案1】:

这个不起作用的原因是Hibernate在后台会生成这样一个SQL:

SELECT * FROM T WHERE JSON_VALUE(?, ?)=?

.. 这不适用于 Oracle。

解决方案是内联这些值。首先是一个小助手类:

public class HibernateInlineExpression extends LiteralExpression<String> {

  public HibernateInlineExpression(CriteriaBuilder criteriaBuilder, String literal) {
      super((CriteriaBuilderImpl) criteriaBuilder, literal);
  }

  @Override
  public String render(RenderingContext renderingContext) {
      return getLiteral();
  }
}

使用上述方法,您现在可以在谓词中执行 JSON 表达式:

cb.equal(cb.function("JSON_VALUE", String.class,
                new HibernateInlineExpression(cb, "JSON_COLUMN"),
                new HibernateInlineExpression(cb, "'$.my.json.property'")),
  new LiteralExpression<>((CriteriaBuilderImpl) cb, String.class, "somevalue"));

当然上面是Hibernate特有的实现,EclipseLink等的用户也得拿出类似的东西。请参阅我的blog post about using JSON functions of Oracle from JPA/Hibernate 了解其他一些技巧。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-12-04
    • 1970-01-01
    • 1970-01-01
    • 2012-01-27
    • 2015-04-04
    • 2013-08-31
    • 2013-06-21
    • 1970-01-01
    相关资源
    最近更新 更多