Ich habe Folgendes in einer Frageentität:
@NamedQuery(name = "Question.allApproved",
query = "SELECT q FROM Question q WHERE q.status = 'APPROVED'")
und
@Enumerated(EnumType.STRING)
private Status status;
// usual accessors
Ich bekomme diese Ausnahme:
Ausnahme Beschreibung: Fehler beim Kompilieren der Abfrage [Question.countApproved:
SELECT COUNT(q) FROM Question q WHERE q.status = 'APPROVED'
], Zeile 1, Spalte 47: Ungültiger Enum-Equal-Ausdruck, Enum-Wert vom Typ kann nicht[myCompnay.application.Status]
mit einem Nicht-Enum-Wert vom Typ verglichen werden[java.lang.String]
. at org.eclipse.persistence.internal.jpa.EntityManagerSetupImpl.deploy (EntityManagerSetupImpl.java:501)
Wie behebe ich das?
java
jakarta-ee
jpa
Lucky Luke
quelle
quelle
Antworten:
Ich denke, Sie sollten Ihre (voll qualifizierte)
Status
Aufzählung anstelle des wörtlichen Werts verwenden, also ungefähr so: (vorausgesetzt, IhreStatus
Aufzählung ist imcom.myexample
Paket enthalten)@NamedQuery(name = "Question.allApproved", query = "SELECT q FROM Question q WHERE q.status = com.myexample.Status.APPROVED").
quelle
@Query
Anmerkung sprichst du?fully qualified
ist wichtiger, als ich dachte.4 Jahre nach dem ersten Posten gibt es einige Entwicklungen. Mit Spring 4 und Hibernate 4 ist es jetzt möglich, Hibernate mit einem SpEL-Ausdruck zu "tricksen". Zum Beispiel:
Die Aufzählung:
package com.mycompany.enums public enum Status { INITIAL, PENDING, REJECTED, APPROVED, SHIPPED, DELIVERED, COMPLETE; }
Hier ist eine Wrapper-Klasse namens 'Filter', die wir an die Repository-Filtermethode übergeben.
package com.mycompany.enums public class Filter implements Serializable { /** The id of the filtered item */ private Integer id; /** The status of the filtered item */ private Status status; // more filter criteria here... // getters, setters, equals(), hashCode() - omitted for brevity /** * Returns the name of the status constant or null if the status is null. This is used in the repositories to filter * queries by the status using a the SPEL (T) expression, taking advantage of the status qualified name. For example: * {@code :#{T(com.mycompany.enums.Status).#filter.statusName}} * * @return the status constant name or null if the status is null */ public String getStatusName() { return null == status ? status : status.name(); } }
Schließlich können wir im Repository jetzt die Filter-Klasse als einzelnen Parameter verwenden und die Abfrage veranlassen, eine Mischung aus Literalen und SpEL-Ausdrücken in ein Status-Objekt zu übersetzen:
Das Repository:
package com.mycompany.repository @Repository public interface OrderRepository extends CrudRepository<Order, Integer> { @Query("SELECT o from Order o " + "WHERE o.id = COALESCE(:#{#filter.id},o.id) " + "AND o.status = COALESCE(:#{T(com.mycompany.enums.Status).#filter.statusName},o.status)") public List<Order> getFilteredOrders(@Param(value = "filter") Filter filter); }
Dies funktioniert einwandfrei, aber aus irgendeinem Grund habe ich es noch nicht herausgefunden. Wenn Sie das SQL-Debugging im Ruhezustand aktivieren und die Ordnerprotokollierung aktivieren, können Sie nicht sehen, dass der Ruhezustand diesen Ausdruck an Abfragevariablen bindet.
quelle
Bitte verwenden Sie die folgende Eigenschaft in application.properties logging.level.org.hibernate.type.descriptor.sql.BasicBinder = TRACE
quelle