JPA Eclipselink子查询在where子句之间,CriteriaBuilder和元模型
我想用元模型执行此查询,但我不能!我不知道该怎么做。
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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
升腾回答晚了,但是..
不确定您在这里想做什么,它可能与您的错误有关,也可能无关。您创建 sqOne 并进行选择。然后重做选择,替换前一个并将结果复制到 horaInicio。这样做的目的是什么?您也可以跳过 sqOne.select(root2.get(Modulos_.inicio)); 并继续使用 sqOne 而不是 horaInicio。
另外,我不确定您是否可以混合和匹配从不同查询创建的根。
Abit late answer but..
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.