validar usar tipo nomenclatura herencia estados enum con comportamiento como java java-ee jpa

usar - tipo enum java



Problemas con hacer una consulta al usar Enum en la entidad (3)

Tengo lo siguiente en una entidad de pregunta:

@NamedQuery(name = "Question.allApproved", query = "SELECT q FROM Question q WHERE q.status = ''APPROVED''")

y

@Enumerated(EnumType.STRING) private Status status; // usual accessors

Estoy recibiendo esta excepción:

Excepción Descripción: Error al compilar la consulta [Question.countApproved: SELECT COUNT(q) FROM Question q WHERE q.status = ''APPROVED'' ], línea 1, columna 47: expresión enum no válida, no se puede comparar el valor enum de tipo [myCompnay.application.Status] con un valor no enum de tipo [java.lang.String] . en org.eclipse.persistence.internal.jpa.EntityManagerSetupImpl.deploy (EntityManagerSetupImpl.java:501)

¿Cómo puedo solucionar esto?


4 años desde la publicación inicial, hay algunos desarrollos. Con Spring 4 e Hibernate 4 ahora es posible ''truco'' Hibernate usando una expresión SpEL. Por ejemplo:

La enumeración:

package com.mycompany.enums public enum Status { INITIAL, PENDING, REJECTED, APPROVED, SHIPPED, DELIVERED, COMPLETE; }

Aquí hay una clase contenedora llamada ''Filtro'' que pasaremos al método de filtrado del repositorio.

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

Finalmente, en el repositorio, ahora podemos usar la clase Filter como parámetro único y hacer que la consulta traduzca lo que parece ser una mezcla de literales y expresiones SpEL a un objeto Status:

El repositorio

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

Esto funciona a la perfección, pero por alguna extraña razón que aún no he descubierto, si habilita la depuración de SQL en Hibernate y activa el registro de enlace, no podrá ver a Hibernate vinculando esta expresión a variables de consulta.


Creo que debería usar su enumeración de Status (totalmente calificada) en lugar del valor literal, así que algo como esto: (suponiendo que su enum de Status esté en el paquete com.myexample )

@NamedQuery(name = "Question.allApproved", query = "SELECT q FROM Question q WHERE q.status = com.myexample.Status.APPROVED").


Utilice la propiedad below en application.properties logging.level.org.hibernate.type.descriptor.sql.BasicBinder = TRACE