JPA Eclipselink Unterabfrage in die where-Klausel mit zwischen, CriteriaBuilder und Metamodell
Ich möchte das query-Metamodell, aber ich kann nicht!! Ich weiß nicht, wie dies zu tun.
MYSQL ABFRAGE (mit dieser Abfrage möchte ich alle Zeilen aus der Clases
Tabelle, die Lehre in diesem 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();
Diese sind meine Einheiten:
PERSON 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...
}
PERSON 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...
}
Habe ich dieses:
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();
Dieser code gibt mir die folgende Ausnahme:
Exception in thread "main" java.lang.Classcastexception-Fehler:
org.eclipse.die Persistenz.intern.jpa.querydef.SubQueryImpl nicht
cast to org.eclipse.die Persistenz.intern.jpa.querydef.ExpressionImpl
Wenn ich die where
- Klausel für diese...
cq.where(cb.between(cb.currentTime(), new Date(), new Date()));
... es funktioniert, aber ohne meine Unterabfrage, dann kann ich sehen, der Fehler kam von meiner Unterabfrage, aber ich weiß nicht, warum, wenn ich den where
- Klausel für diese...
cq.where(cb.greaterThan(cb.currentTime(), horaInicio));
... Ich bekomme diese:
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))))
Kann ich sehen, das problem sind die 2 Unterabfragen in der zwischen-Klausel.
Bitte ich brauche Hilfe mit diesem, ich verbrachte 2 Wochen auf der Suche nach einer Antwort, aber... nichts... Hilfe.
Ich bin mit JPA 2.0 mit Netbeans und EclipseLink mit Metamodell-generator und Java 6.
Ich möchte es mit metamodellen und criteriasbuilder und criteriasquerys
Wie Sie sehen können, die ich tun müssen, um eine Unterabfrage in der where
- Klausel und in diesem where
- Klausel ich muss between
wo die einzelnen parameter haben eine Unterabfrage, wie diese:
SELECT * FROM X WHERE CURRENT_TIME BETWEEN **MY_SUBQUERY_ONE** AND **MY_SUBQUERY_TWO**
Du musst angemeldet sein, um einen Kommentar abzugeben.
Abit späte Antwort aber..
Nicht sicher, was Sie hier zu tun versuchen, und es möglicherweise oder möglicherweise nicht für Ihre Fehler. Sie erstellen sqOne und eine Auswahl treffen. Dann wiederholen Sie die Auswahl, und ersetzen die vorherigen, und kopieren Sie das Ergebnis in horaInicio. Was ist der Zweck dieses? Sie könnten aswell überspringen
sqOne.select(root2.get(Modulos_.inicio));
und halten mit sqOne statt horaInicio.Außerdem bin ich nicht sicher, dass Sie können mix and match-Wurzeln erstellt aus verschiedenen Abfragen.