JPA Eclipselink子查询在where子句之间,CriteriaBuilder和元模型

发布于 2024-10-20 02:03:16 字数 4351 浏览 1 评论 0原文

我想用元模型执行此查询,但我不能!我不知道该怎么做。

MYSQL QUERY(通过此查询,我想从此刻正在教学的 Classes 表中获取所有行):

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< /strong>

@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
@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))))

我可以看到问题是 2 个子查询之间的子句。

我需要这方面的帮助,我花了两周时间寻找答案,但是……没有任何帮助。 我将 JPA 2.0 与 Netbeans 结合使用,将 EclipseLink 与元模型生成器和 Java 6 结合使用。 我想使用元模型、criteriasbuilder 和 criteriasquerys 来完成此操作

如您所见,我需要在 where 子句中执行子查询,在 where 子句中我需要执行 < code> Between 其中每个参数都有一个子查询,如下所示:

SELECT * FROM X WHERE CURRENT_TIME BETWEEN **MY_SUBQUERY_ONE** AND **MY_SUBQUERY_TWO**

I want to do this query with metamodel but I can't!! I dont know how to do this.

MYSQL QUERY (with this query I want to get all the rows from the Clases table that are teaching in this moment):

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();

These are my entities:

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...
}

I have this:

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();

This code gives me the following exception:

Exception in thread "main" java.lang.ClassCastException:
org.eclipse.persistence.internal.jpa.querydef.SubQueryImpl cannot be
cast to org.eclipse.persistence.internal.jpa.querydef.ExpressionImpl

If i change the where clause for this one...

cq.where(cb.between(cb.currentTime(), new Date(), new Date()));

... it works but without my Subquery, then i can see the error came from my subquery, but I don't know why, if I change the where clause for this one...

cq.where(cb.greaterThan(cb.currentTime(), horaInicio));

... I get this:

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))))

I can see the problem are the 2 subqueries in the between clause.

Please I need help with this, I spent 2 weeks looking for an answer but... nothing... help.
I'm using JPA 2.0 with Netbeans and EclipseLink with metamodel generator and Java 6.
I want to do it with metamodels and criteriasbuilder and criteriasquerys

As you can see i need to do a subquery in the where clause and in that where clause I need to do a between where each parameter have a subquery, like this:

SELECT * FROM X WHERE CURRENT_TIME BETWEEN **MY_SUBQUERY_ONE** AND **MY_SUBQUERY_TWO**

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

晚风撩人 2024-10-27 02:03:16

升腾回答晚了,但是..

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。

另外,我不确定您是否可以混合和匹配从不同查询创建的根。

Abit late answer but..

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)
    )
);

Not sure what you are trying to do here, and it might or might not be related to your error. You create sqOne and make a selection. Then you redo the selection, replacing the previous one and copy the result to horaInicio. What is the purpose of this? You might aswell skip sqOne.select(root2.get(Modulos_.inicio)); and keep using sqOne instead of horaInicio.

Also, I'm not sure you can mix and match Roots created from different queries.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文