2017-01-25 21 views
0

まず、長い記事を残して申し訳ありませんが、それは複雑な問題です。JPA 2.0 Criteria API:大文字と小文字の句を使用して選択

当社の製品は、現在の基準APIを使用して、次の作業のクエリを持っている:

:(CASE文を追加しました)私の目標は、SELECT句のクエリを次のように変更を加えることである
SELECT 
    pedido0_.rap_num_doc as col_0_0_, 
    pedido0_.rap_cod_tip_doc as col_0_1_, 
    pedido0_.rap_ver_doc as col_0_2_, 
    pedido0_.edo_cod_est_doc as col_1_0_, 
    pedido0_.tip_can as col_2_0_, 
    pedido0_.num_pro_rea as col_3_0_, 
    pedido0_.cod_uti_ges_ped as col_4_0_, 
    pedido0_.nom_ges_ped as col_5_0_, 
    pedido0_.dte_nifap as col_6_0_, 
    pedido0_.nom_tit as col_7_0_, 
    pedido0_.cod_uti_cri as col_8_0_, 
    pedido0_.uor_cod_uni_org as col_9_0_, 
    pedido0_.chv_cod_tip_ped as col_10_0_, 
    estadopedi3_.cod_est_ped as col_11_0_, 
    procedimen1_.cod_pro_ped as col_12_0_, 
    tipodecisa2_.cod_tip_dec_ped as col_13_0_, 
    pedido0_.uti_codigo as col_14_0_ 
FROM 
    rap_pedido pedido0_ 
LEFT OUTER JOIN 
    rap_pro_ped procedimen1_ 
     on pedido0_.chv_cod_pro_ped=procedimen1_.cod_pro_ped 
LEFT OUTER JOIN 
    rap_tip_dec_ped tipodecisa2_ 
     on pedido0_.chv_cod_tip_dec_ped=tipodecisa2_.cod_tip_dec_ped 
LEFT OUTER JOIN 
    rap_est_ped estadopedi3_ 
     on pedido0_.chv_cod_est_ped=estadopedi3_.cod_est_ped 
INNER JOIN 
    rap_tip_ped tipopedido4_ 
     on pedido0_.chv_cod_tip_ped=tipopedido4_.cod_tip_ped 
WHERE 
    pedido0_.dte_nif=? 

:私は次のコードを使用して、現在のselect句を適応してきたこれを達成するために
SELECT 
    pedido0_.rap_num_doc as col_0_0_, 
    pedido0_.rap_cod_tip_doc as col_0_1_, 
    pedido0_.rap_ver_doc as col_0_2_, 
    pedido0_.edo_cod_est_doc as col_1_0_, 
    pedido0_.tip_can as col_2_0_, 
    pedido0_.num_pro_rea as col_3_0_, 
    pedido0_.cod_uti_ges_ped as col_4_0_, 
    pedido0_.nom_ges_ped as col_5_0_, 
    pedido0_.dte_nifap as col_6_0_, 
    pedido0_.nom_tit as col_7_0_, 
    pedido0_.cod_uti_cri as col_8_0_, 
    pedido0_.uor_cod_uni_org as col_9_0_, 
    pedido0_.chv_cod_tip_ped as col_10_0_, 
    estadopedi3_.cod_est_ped as col_11_0_, 
    procedimen1_.cod_pro_ped as col_12_0_, 
    tipodecisa2_.cod_tip_dec_ped as col_13_0_, 
    pedido0_.uti_codigo as col_14_0_ , 
    CASE WHEN (pedido0_.rap_ver_doc = (
      SELECT MAX(a.rap_ver_doc) 
      FROM rap_pedido a 
      WHERE a.rap_num_doc = pedido0_.rap_num_doc AND a.rap_cod_tip_doc = pedido0_.rap_cod_tip_doc AND a.edo_cod_est_doc > 3 AND NOT EXISTS (
       SELECT 1 
       FROM rap_pedido b 
       WHERE b.rap_cod_tip_doc = a.rap_cod_tip_doc AND b.rap_num_doc = a.rap_num_doc AND b.rap_ver_doc > a.rap_ver_doc AND b.edo_cod_est_doc > 0 
      ) 
     ) 
    ) THEN true ELSE false END 
FROM 
    rap_pedido pedido0_ 
LEFT OUTER JOIN 
    rap_pro_ped procedimen1_ 
     on pedido0_.chv_cod_pro_ped=procedimen1_.cod_pro_ped 
LEFT OUTER JOIN 
    rap_tip_dec_ped tipodecisa2_ 
     on pedido0_.chv_cod_tip_dec_ped=tipodecisa2_.cod_tip_dec_ped 
LEFT OUTER JOIN 
    rap_est_ped estadopedi3_ 
     on pedido0_.chv_cod_est_ped=estadopedi3_.cod_est_ped 
INNER JOIN 
    rap_tip_ped tipopedido4_ 
     on pedido0_.chv_cod_tip_ped=tipopedido4_.cod_tip_ped 
WHERE 
    pedido0_.dte_nif=? 

次のようにサブクエリ法呼び出さ

// Begin new code 
Subquery<Integer> subqueryUltimaVersaoDocumentoSubmetidoSemOutroCriado = criarSubqueryUltimaVersaoDocumentoSubmetidoSemOutroCriado(builder, 
     query, fromPedido); 
Case<Boolean> booleanCase = builder.<Boolean> selectCase(); 
Predicate versaoIgual = builder.equal(fromPedido.get(Pedido_.id).get(PedidoPK_.versaoDocumento), 
     subqueryUltimaVersaoDocumentoSubmetidoSemOutroCriado); 
Expression<Boolean> isSubstituicaoPermitida = booleanCase.when(versaoIgual, true).otherwise(false); 
// End new code 

query.select(builder.construct(Pedido.class, fromPedido.get(Pedido_.id), fromPedido.get(Pedido_.estadoDocumento), 
     fromPedido.get(Pedido_.tipoCandidatura), fromPedido.get(Pedido_.numeroProcesso), fromPedido.get(Pedido_.utilizadorGestor), 
     fromPedido.get(Pedido_.nomeGestor), fromPedido.get(Pedido_.nifapBeneficiario), fromPedido.get(Pedido_.nomeTitular), 
     fromPedido.get(Pedido_.utilizadorCriacao), fromPedido.get(Pedido_.unidadeOrganicaBeneficiario), fromPedido.get(Pedido_.tipoPedido), 
     joinEstadoPedido, joinProcedimento, joinTipoDecisao, fromPedido.get(Pedido_.utilizadorProprietario), isSubstituicaoPermitida)); 

は以下のとおりです。

private Subquery<Integer> criarSubqueryUltimaVersaoDocumentoSubmetidoSemOutroCriado(final CriteriaBuilder builder, 
     final CriteriaQuery<Pedido> query, final Root<Pedido> fromPedido) { 
    // Select max(a.rap_ver_doc) From rap_pedido a Where a.rap_num_doc = pedido0_.rap_num_doc and a.rap_cod_tip_doc = pedido0_.rap_cod_tip_doc and 
    // a.edo_cod_est_doc > 3 and not exists ... 
    final Subquery<Integer> subqueryUltimaVersaoSubmetida = query.subquery(Integer.class); 

    final Root<Pedido> fromUltimaVersaoPedido = subqueryUltimaVersaoSubmetida.from(Pedido.class); 

    subqueryUltimaVersaoSubmetida.select(builder.max(fromUltimaVersaoPedido.get(Pedido_.id).get(PedidoPK_.versaoDocumento))); 

    final List<Predicate> where = new ArrayList<>(); 

    adicionarWhereEquals(builder, where, fromUltimaVersaoPedido.get(Pedido_.id).get(PedidoPK_.tipoDocumento), 
      fromPedido.get(Pedido_.id).get(PedidoPK_.tipoDocumento)); 
    adicionarWhereEquals(builder, where, fromUltimaVersaoPedido.get(Pedido_.id).get(PedidoPK_.numeroDocumento), 
      fromPedido.get(Pedido_.id).get(PedidoPK_.numeroDocumento)); 

    // Considera todos os pedidos cujo estado seja igual ou maior ao estado passado como argumento 
    adicionarWhereGreaterThanOrEqualTo(builder, where, fromUltimaVersaoPedido.get(Pedido_.estadoDocumento), 
      EstadoDocumentoPedido.SUBMETIDO.getId()); 

    builder.not(builder.exists(criarSubqueryExisteDocumentoCriado(builder, query, fromUltimaVersaoPedido))); 

    subqueryUltimaVersaoSubmetida.where(where.toArray(new Predicate[0])); 
    return subqueryUltimaVersaoSubmetida; 
} 

private Subquery<Integer> criarSubqueryExisteDocumentoCriado(CriteriaBuilder builder, CriteriaQuery<Pedido> query, Root<Pedido> fromPedido) { 
    // select 1 from rap_pedido b where b.rap_cod_tip_doc = a.rap_cod_tip_doc and b.rap_num_doc = a.rap_num_doc and b.rap_ver_doc > a.rap_ver_doc 
    // and b.edo_cod_est_doc > 0 
    final Subquery<Integer> subqueryUltimaVersao = query.subquery(Integer.class); 

    final Root<Pedido> fromUltimaVersaoPedido = subqueryUltimaVersao.from(Pedido.class); 

    subqueryUltimaVersao.select(builder.literal(1)); 

    final List<Predicate> where = new ArrayList<>(); 

    adicionarWhereEquals(builder, where, fromUltimaVersaoPedido.get(Pedido_.id).get(PedidoPK_.tipoDocumento), 
      fromPedido.get(Pedido_.id).get(PedidoPK_.tipoDocumento)); 
    adicionarWhereEquals(builder, where, fromUltimaVersaoPedido.get(Pedido_.id).get(PedidoPK_.numeroDocumento), 
      fromPedido.get(Pedido_.id).get(PedidoPK_.numeroDocumento)); 

    adicionarWhereGreaterThan(builder, where, fromUltimaVersaoPedido.get(Pedido_.id).get(PedidoPK_.versaoDocumento), 
      fromPedido.get(Pedido_.id).get(PedidoPK_.versaoDocumento)); 

    adicionarWhereGreaterThan(builder, where, fromUltimaVersaoPedido.get(Pedido_.estadoDocumento), 0); 

    subqueryUltimaVersao.where(where.toArray(new Predicate[0])); 
    return subqueryUltimaVersao; 
} 

protected void adicionarWhereEquals(CriteriaBuilder builder, List<Predicate> where, Expression<?> coluna1, Expression<?> coluna2) { 
    where.add(builder.equal(coluna1, coluna2)); 
} 

protected void adicionarWhereEquals(CriteriaBuilder builder, List<Predicate> where, Expression<?> coluna, Object parametro) { 
    where.add(builder.equal(coluna, parametro)); 
} 

@SuppressWarnings({ "rawtypes", "unchecked" }) 
protected void adicionarWhereGreaterThanOrEqualTo(CriteriaBuilder builder, List<Predicate> where, Expression coluna, Comparable parametro) { 
    where.add(builder.greaterThanOrEqualTo(coluna, parametro)); 
} 

@SuppressWarnings({ "rawtypes", "unchecked" }) 
protected void adicionarWhereGreaterThanOrEqualTo(CriteriaBuilder builder, List<Predicate> where, Expression coluna1, Expression coluna2) { 
    where.add(builder.greaterThanOrEqualTo(coluna1, coluna2)); 
} 

@SuppressWarnings("unchecked") 
protected void adicionarWhereGreaterThan(CriteriaBuilder builder, List<Predicate> where, Expression coluna1, Expression coluna2) { 
    where.add(builder.greaterThan(coluna1, coluna2)); 
} 

@SuppressWarnings("unchecked") 
protected void adicionarWhereGreaterThan(CriteriaBuilder builder, List<Predicate> where, Expression coluna, Comparable parametro) { 
    where.add(builder.greaterThanOrEqualTo(coluna, parametro)); 
} 

クエリを呼び出すときしかし、私は次の例外を取得します。 select句に追加されたサブクエリのタイプによって、私は同じ結果になります。これには回避策がありますか?

Caused by: java.lang.ClassCastException: org.hibernate.hql.internal.ast.tree.ParameterNode cannot be cast to org.hibernate.hql.internal.ast.tree.SelectExpression 
    at org.hibernate.hql.internal.ast.tree.CaseNode.getFirstThenNode(CaseNode.java:43) [hibernate-core-4.2.0.Final-redhat-1.jar:4.2.0.Final-redhat-1] 
    at org.hibernate.hql.internal.ast.tree.CaseNode.getDataType(CaseNode.java:39) [hibernate-core-4.2.0.Final-redhat-1.jar:4.2.0.Final-redhat-1] 
    at org.hibernate.hql.internal.ast.tree.ConstructorNode.resolveConstructorArgumentTypes(ConstructorNode.java:166) [hibernate-core-4.2.0.Final-redhat-1.jar:4.2.0.Final-redhat-1] 
    at org.hibernate.hql.internal.ast.tree.ConstructorNode.prepare(ConstructorNode.java:141) [hibernate-core-4.2.0.Final-redhat-1.jar:4.2.0.Final-redhat-1] 
    at org.hibernate.hql.internal.ast.HqlSqlWalker.processConstructor(HqlSqlWalker.java:1019) [hibernate-core-4.2.0.Final-redhat-1.jar:4.2.0.Final-redhat-1] 
    at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.selectExpr(HqlSqlBaseWalker.java:2279) [hibernate-core-4.2.0.Final-redhat-1.jar:4.2.0.Final-redhat-1] 
    at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.selectExprList(HqlSqlBaseWalker.java:2145) [hibernate-core-4.2.0.Final-redhat-1.jar:4.2.0.Final-redhat-1] 
    at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.selectClause(HqlSqlBaseWalker.java:1451) [hibernate-core-4.2.0.Final-redhat-1.jar:4.2.0.Final-redhat-1] 
    at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.query(HqlSqlBaseWalker.java:571) [hibernate-core-4.2.0.Final-redhat-1.jar:4.2.0.Final-redhat-1] 
    at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.selectStatement(HqlSqlBaseWalker.java:299) [hibernate-core-4.2.0.Final-redhat-1.jar:4.2.0.Final-redhat-1] 
    at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.statement(HqlSqlBaseWalker.java:247) [hibernate-core-4.2.0.Final-redhat-1.jar:4.2.0.Final-redhat-1] 
    at org.hibernate.hql.internal.ast.QueryTranslatorImpl.analyze(QueryTranslatorImpl.java:248) [hibernate-core-4.2.0.Final-redhat-1.jar:4.2.0.Final-redhat-1] 
    at org.hibernate.hql.internal.ast.QueryTranslatorImpl.doCompile(QueryTranslatorImpl.java:183) [hibernate-core-4.2.0.Final-redhat-1.jar:4.2.0.Final-redhat-1] 
    at org.hibernate.hql.internal.ast.QueryTranslatorImpl.compile(QueryTranslatorImpl.java:136) [hibernate-core-4.2.0.Final-redhat-1.jar:4.2.0.Final-redhat-1] 
    at org.hibernate.engine.query.spi.HQLQueryPlan.<init>(HQLQueryPlan.java:105) [hibernate-core-4.2.0.Final-redhat-1.jar:4.2.0.Final-redhat-1] 
    at org.hibernate.engine.query.spi.HQLQueryPlan.<init>(HQLQueryPlan.java:80) [hibernate-core-4.2.0.Final-redhat-1.jar:4.2.0.Final-redhat-1] 
    at org.hibernate.engine.query.spi.QueryPlanCache.getHQLQueryPlan(QueryPlanCache.java:168) [hibernate-core-4.2.0.Final-redhat-1.jar:4.2.0.Final-redhat-1] 
    at org.hibernate.internal.AbstractSessionImpl.getHQLQueryPlan(AbstractSessionImpl.java:221) [hibernate-core-4.2.0.Final-redhat-1.jar:4.2.0.Final-redhat-1] 
    at org.hibernate.internal.AbstractSessionImpl.createQuery(AbstractSessionImpl.java:199) [hibernate-core-4.2.0.Final-redhat-1.jar:4.2.0.Final-redhat-1] 
    at org.hibernate.internal.SessionImpl.createQuery(SessionImpl.java:1777) [hibernate-core-4.2.0.Final-redhat-1.jar:4.2.0.Final-redhat-1] 
    at org.hibernate.ejb.AbstractEntityManagerImpl.createQuery(AbstractEntityManagerImpl.java:452) [hibernate-entitymanager-4.2.0.Final-redhat-1.jar:4.2.0.Final-redhat-1] 
    at org.hibernate.ejb.criteria.CriteriaQueryCompiler.compile(CriteriaQueryCompiler.java:221) [hibernate-entitymanager-4.2.0.Final-redhat-1.jar:4.2.0.Final-redhat-1] 
    at org.hibernate.ejb.AbstractEntityManagerImpl.createQuery(AbstractEntityManagerImpl.java:587) [hibernate-entitymanager-4.2.0.Final-redhat-1.jar:4.2.0.Final-redhat-1] 
    at org.jboss.as.jpa.container.AbstractEntityManager.createQuery(AbstractEntityManager.java:96) [jboss-as-jpa-7.1.1.Final.jar:7.1.1.Final] 
    .... 

ありがとう!

答えて

0

私は答えを見つけたと思います。

明らかに、JPA 2.0とHibernate 4.2.0をプロバイダとして使用しているため、これは不可能です。 select句のサブクエリは、this post.

に従ってJPA 2.1およびHibernate 5.0以降でのみサポートされています
関連する問題