Mam następujące elementy w encji Pytanie:
@NamedQuery(name = "Question.allApproved",
query = "SELECT q FROM Question q WHERE q.status = 'APPROVED'")
i
@Enumerated(EnumType.STRING)
private Status status;
// usual accessors
Otrzymuję ten wyjątek:
Opis wyjątku: Błąd podczas kompilowania kwerendy [Question.countApproved:
SELECT COUNT(q) FROM Question q WHERE q.status = 'APPROVED'
], wiersz 1, kolumna 47: nieprawidłowe wyliczenie równe, nie można porównać wartości wyliczenia typu[myCompnay.application.Status]
z wartością typu innego niż wyliczenie[java.lang.String]
. w org.eclipse.persistence.internal.jpa.EntityManagerSetupImpl.deploy (EntityManagerSetupImpl.java:501)
Jak to naprawić?
java
jakarta-ee
jpa
Lucky Luke
źródło
źródło
Odpowiedzi:
Myślę, że powinieneś użyć swojego (w pełni kwalifikowanego)
Status
wyliczenia zamiast wartości dosłownej, więc coś takiego: (zakładając, że twojeStatus
wyliczenie jest wcom.myexample
pakiecie)@NamedQuery(name = "Question.allApproved", query = "SELECT q FROM Question q WHERE q.status = com.myexample.Status.APPROVED").
źródło
@Query
jakiej adnotacji mówisz?fully qualified
jest ważniejsze niż myślałem, że może być.Po 4 latach od pierwszego stanowiska nastąpiły pewne zmiany. Używając spring 4 i Hibernate 4, można teraz „oszukać” Hibernate, używając wyrażenia SpEL. Na przykład:
Wyliczenie:
package com.mycompany.enums public enum Status { INITIAL, PENDING, REJECTED, APPROVED, SHIPPED, DELIVERED, COMPLETE; }
Oto klasa opakowania o nazwie „Filter”, którą przekażemy do metody filtrowania repozytorium.
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(); } }
Wreszcie w repozytorium możemy teraz użyć klasy Filter jako pojedynczego parametru i sprawić, że zapytanie przetłumaczy coś, co wydaje się być mieszaniną literałów i wyrażeń SpEL na obiekt Status:
Repozytorium:
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); }
Działa to doskonale, ale z jakiegoś dziwnego powodu, którego jeszcze nie rozgryzłem, jeśli włączysz debugowanie SQL w hibernacji i włączysz rejestrowanie spinacza, nie będziesz w stanie zobaczyć Hibernacji wiążącej to wyrażenie ze zmiennymi zapytania.
źródło
Użyj poniższej właściwości w application.properties logging.level.org.hibernate.type.descriptor.sql.BasicBinder = TRACE
źródło