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