title: How to create custom predicate for criteria jpa2 (hibernate)?
body: <p>I'm trying migrate to JPA2 Criteria API (Hibernate as JPA provider) from the old one. I have a problem with custom criteria for PostgreSQL JSONB type. In the previous Criteria implementation it can be done by creating SQLCriterion where I can operate directly on native SQL. In the JPA2 implementation I cannot find similar solution so I have decided to extend AbstractSimplePredicate. </p>
  
  <p>Here simple version:</p>
  
  <pre><code>   class JsonEqual&lt;Y&gt; extends AbstractSimplePredicate {
  
      private static final String JSON_NESTED_FIELD_EXTRACTOR = "-&gt;&gt;";
      private static final String JSON_EQUAL_OPERATOR = "=";
      private final Expression&lt;?&gt; field;
      private final Expression&lt;?&gt; value;
      private final Path&lt;Y&gt; path;
  
      public JsonEqual(CriteriaBuilderImpl cb, Path&lt;Y&gt; path, Expression&lt;?&gt; field, Expression&lt;?&gt; value) {
          super(cb);
          this.path = path;
          this.field = field;
          this.value = value;
      }
  
      @Override
      public void registerParameters(ParameterRegistry registry) {
          Helper.possibleParameter(path, registry);
          Helper.possibleParameter(field, registry);
          Helper.possibleParameter(value, registry);
      }
  
      @Override
      public String render(boolean isNegated, RenderingContext renderingContext) {
          return ((Renderable) path).render(renderingContext)
                          + JSON_NESTED_FIELD_EXTRACTOR
                          + ((Renderable) field).render(renderingContext)
                          + JSON_EQUAL_OPERATOR
                          + ((Renderable) value).render(renderingContext);
      }
  }
  </code></pre>
  
  <p>Problem occurs when jpa2 criteria is compiled to HQL. Query part rendered by predicate is incorrect format ('->>' operator is not recognized).</p>
  
  <pre><code>org.hibernate.hql.internal.ast.QuerySyntaxException: unexpected token: &gt; near line 1, column 515 [select new com.hibernate.VenueEntity(generatedAlias0.id) from com.hibernate.VenueEntity as generatedAlias0 where ( generatedAlias0.metadata-&gt;&gt;:param3=:param4 ) order by generatedAlias0.created asc]
  at org.hibernate.hql.internal.ast.QuerySyntaxException.convert(QuerySyntaxException.java:74) ~[hibernate-core-5.2.12.Final.jar:5.2.12.Final]
  at org.hibernate.hql.internal.ast.ErrorCounter.throwQueryException(ErrorCounter.java:91) ~[hibernate-core-5.2.12.Final.jar:5.2.12.Final]
  at org.hibernate.hql.internal.ast.QueryTranslatorImpl.parse(QueryTranslatorImpl.java:291) ~[hibernate-core-5.2.12.Final.jar:5.2.12.Final]
  at org.hibernate.hql.internal.ast.QueryTranslatorImpl.doCompile(QueryTranslatorImpl.java:186) ~[hibernate-core-5.2.12.Final.jar:5.2.12.Final]
  at org.hibernate.hql.internal.ast.QueryTranslatorImpl.compile(QueryTranslatorImpl.java:141) ~[hibernate-core-5.2.12.Final.jar:5.2.12.Final]
  at org.hibernate.engine.query.spi.HQLQueryPlan.&lt;init&gt;(HQLQueryPlan.java:115) ~[hibernate-core-5.2.12.Final.jar:5.2.12.Final]
  at org.hibernate.engine.query.spi.HQLQueryPlan.&lt;init&gt;(HQLQueryPlan.java:77) ~[hibernate-core-5.2.12.Final.jar:5.2.12.Final]
  at org.hibernate.engine.query.spi.QueryPlanCache.getHQLQueryPlan(QueryPlanCache.java:153) ~[hibernate-core-5.2.12.Final.jar:5.2.12.Final]
  at org.hibernate.internal.AbstractSharedSessionContract.getQueryPlan(AbstractSharedSessionContract.java:553) ~[hibernate-core-5.2.12.Final.jar:5.2.12.Final]
  at org.hibernate.internal.AbstractSharedSessionContract.createQuery(AbstractSharedSessionContract.java:662) ~[hibernate-core-5.2.12.Final.jar:5.2.12.Final]
  at org.hibernate.internal.SessionImpl.createQuery(SessionImpl.java:3324) ~[hibernate-core-5.2.12.Final.jar:5.2.12.Final]
  at org.hibernate.query.criteria.internal.CriteriaQueryImpl$1.buildCompiledQuery(CriteriaQueryImpl.java:318) ~[hibernate-core-5.2.12.Final.jar:5.2.12.Final]
  at org.hibernate.query.criteria.internal.compile.CriteriaCompiler.compile(CriteriaCompiler.java:149) ~[hibernate-core-5.2.12.Final.jar:5.2.12.Final]
  at org.hibernate.internal.SessionImpl.createQuery(SessionImpl.java:3617) ~[hibernate-core-5.2.12.Final.jar:5.2.12.Final]
  at org.hibernate.internal.SessionImpl.createQuery(SessionImpl.java:203) ~[hibernate-core-5.2.12.Final.jar:5.2.12.Final]
  at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_152]
  at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_152]
  at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_152]
  at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_152]
  </code></pre>
  
  <p>Is there any possibility to implement custom Predicate for JPA2 in this situation?</p>