如何使用JPA / EclipseLink Criteria api在GROUP BY子句中编写SUBSTR函数

时间:2016-01-11 15:19:53

标签: java oracle jpa eclipselink

我必须根据操作执行的年份对存储的各种操作进行分组,并获取所执行的每个操作的计数。我正在使用eclipselink 2.4.2。以下是我尝试过的内容

BuildOperation.java

@Table(name = "BUILD_OPERATION")
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@MappedSuperclass
@DiscriminatorColumn(name = "BUILD_OP_TYPE_ID", discriminatorType = DiscriminatorType.INTEGER)
@javax.persistence.Entity
@SequenceGenerator(name = "BUILD_OPERATION_SEQ", sequenceName = "BUILD_OPERATION_SEQ", allocationSize = 1, initialValue = 1)
public class BuildOperation implements Entity, Serializable {

    @Id
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "BUILD_OPERATION_SEQ")
    @Column(name = "BUILD_OPERATION_ID", nullable = false)
    public BigDecimal buildOperationId;
    @Column(name = "BUILD_OP_TYPE_ID", nullable = false)
    public Integer buildOpTypeId;
    @Column(name = "STATUS_ID")
    public BigDecimal statusId;
    @Column(name = "CREATED_ON", nullable = false)
    public Timestamp createdOn;
}

Query.java

CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<Tuple> q = cb.createTupleQuery();

Root<BuildOperation> bo = q.from(BuildOperation.class);

final Expression<String> year = cb.substring(cb.function("TO_CHAR", String.class, bo.get("createdOn"), cb.literal("'YYYY-MM-DD'")), cb.literal(2), cb.literal(4));

q.multiselect(bo.get("buildOpTypeId"), year , cb.count(bo.get("buildOpTypeId").as(Number.class)));
q.groupBy(bo.get("buildOpTypeId"), year);

TypedQuery<Tuple> query = em.createQuery(q);
return query.getResultList();

以上代码抛出异常:java.sql.SQLSyntaxErrorException: ORA-00979: not a GROUP BY expression

从eclipselink跟踪中,跟踪中的等效查询是

 SELECT BUILD_OP_TYPE_ID, SUBSTR(TO_CHAR(CREATED_ON, ?), ?, ?), COUNT(BUILD_OP_TYPE_ID) FROM BUILD_OPERATION GROUP BY BUILD_OP_TYPE_ID, SUBSTR(TO_CHAR(CREATED_ON, ?), ?, ?)

绑定['YYYY-MM-DD', 2, 4, 'YYYY-MM-DD', 2, 4]。如果我从sqldeveloper执行它,它可以工作。你能不能透露一下我应该怎样做才能使这项工作符合标准api?

提出类似的问题before

0 个答案:

没有答案