JPA Eclipselink Subquery in where子句,CriteriaBuilder和metamodel

我想用metamodel做这个查询,但我不能!我不知道该怎么做。 MYSQL QUERY(使用此查询我想从
Clases
表中获取此刻教学的所有行):
SELECT * FROM clases cl 
WHERE CURRENT_TIME() BETWEEN
(SELECT ml2.inicio FROM modulos ml2 WHERE cl.modulo_id=ml2.modulo_id ) AND 
(SELECT ml2.fin FROM modulos ml2 WHERE cl.modulo_id=ml2.modulo_id) AND
 cl.fecha=CURRENT_DATE();
这些是我的实体: ENTITY MODULOS
@Entity
@Table(name = "modulos")
public class Modulos implements Serializable {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Basic(optional = false)
    @Column(name = "modulo_id")
    private Integer moduloId;

    @Basic(optional = false)
    @Column(name = "inicio")
    @Temporal(TemporalType.TIME)
    private Date inicio;

    @Basic(optional = false)
    @Column(name = "fin")
    @Temporal(TemporalType.TIME)
    private Date fin;

    @Basic(optional = false)
    @Column(name = "modulo")
    private String modulo;

    @OneToMany(cascade = CascadeType.ALL, mappedBy = "modulos")
    private List<GruposHorarioHasModulos> gruposHorarioHasModulosList;

    //getters and setters...
}
ENTITY CLASES
@Entity
@Table(name = "clases")
public class Clases implements Serializable {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Basic(optional = false)
    @Column(name = "clase_id")
    private Integer claseId;

    @Basic(optional = false)
    @Column(name = "aula")
    private String aula;

    @Basic(optional = false)
    @Column(name = "fusion")
    private boolean fusion = false;

    @Basic(optional = false)
    @Column(name = "clase_numero")
    private Integer claseNumero;

    @Basic(optional = false)
    @Column(name = "clase_impartida")
    private boolean claseImpartida = false;

    @JoinColumn(name = "modulo_id", referencedColumnName = "modulo_id")
    @ManyToOne(optional = false)
    private Modulos modulos;

    //getters and setters...
}
我有这个:
EntityManager em1 = Persistence.createEntityManagerFactory("myPU").createEntityManager();
CriteriaBuilder cb = em1.getCriteriaBuilder();
CriteriaQuery cq = cb.createQuery();
Root<Clases> root = cq.from(Clases.class);
cq.select(root.get(Clases_.claseId));

Subquery<Date> sqOne = cq.subquery(Date.class);
Root<Modulos> root2 = sqOne.from(Modulos.class);
sqOne.select(root2.get(Modulos_.inicio));

Subquery<Date> horaInicio = sqOne.select(root2.get(Modulos_.inicio)).where(
        cb.equal(
            root2.get(Modulos_.moduloId),
            root.get(Clases_.modulos).get(Modulos_.moduloId)
            )
        );

Subquery<Date> sqTwo = cq.subquery(Date.class);
Root<Modulos> root3 = sqTwo.from(Modulos.class);
Subquery<Date> horaFin = sqTwo.select(root3.get(Modulos_.fin)).where(
        cb.equal(
            root3.get(Modulos_.moduloId),
            root.get(Clases_.modulos).get(Modulos_.moduloId)
            )
        );

cq.where(cb.between(cb.currentTime(), horaInicio, horaFin));
em1.createQuery(cq).getResultList();
此代码给出了以下异常:   线程“main”java.lang.ClassCastException中的异常:   org.eclipse.persistence.internal.jpa.querydef.SubQueryImpl不能   强制转换为org.eclipse.persistence.internal.jpa.querydef.ExpressionImpl 如果我改变这个的
where
条款......
cq.where(cb.between(cb.currentTime(), new Date(), new Date()));
...它有效,但没有我的子查询,那么我可以看到错误来自我的子查询,但我不知道为什么,如果我改变这个的
where
条款...
cq.where(cb.greaterThan(cb.currentTime(), horaInicio));
......我明白了:
SELECT t0.clase_id FROM clases t0, clases t1 WHERE (CURRENT_TIME > (SELECT t2.inicio FROM modulos t3, modulos t2 WHERE ((t2.modulo_id = t3.modulo_id) AND (t3.modulo_id = t0.modulo_id))))
我可以看到问题是between子句中的2个子查询。 我需要帮助,我花了两周时间寻找答案,但......没有...帮助。 我正在使用带有Netbeans的JPA 2.0和带有元模型生成器和Java 6的EclipseLink。 我想用metamodels和criteriasbuilder和criteriasquerys来做 正如你所看到的,我需要在
where
子句中做一个子查询,在那个
where
子句中我需要做一个
between
,其中每个参数都有一个子查询,如下所示:
SELECT * FROM X WHERE CURRENT_TIME BETWEEN **MY_SUBQUERY_ONE** AND **MY_SUBQUERY_TWO**
    
已邀请:
升技晚回答但是......
Subquery<Date> sqOne = cq.subquery(Date.class);
Root<Modulos> root2 = sqOne.from(Modulos.class);
sqOne.select(root2.get(Modulos_.inicio));

Subquery<Date> horaInicio = sqOne.select(root2.get(Modulos_.inicio)).where(
    cb.equal(
        root2.get(Modulos_.moduloId),
        root.get(Clases_.modulos).get(Modulos_.moduloId)
    )
);
不确定你在这里尝试做什么,它可能与你的错误有关,也可能没有。您创建sqOne并进行选择。然后重做选择,替换前一个并将结果复制到horaInicio。这样做的目的是什么?你也可以跳过
sqOne.select(root2.get(Modulos_.inicio));
并继续使用sqOne而不是horaInicio。 此外,我不确定您可以混合和匹配从不同查询创建的根。     

要回复问题请先登录注册