4 ans après le post initial, il y a du nouveau. En utilisant Spring 4 et Hibernate 4, il est maintenant possible de "tromper" Hibernate en utilisant une expression SpEL. Par exemple :
L'énumération :
package com.mycompany.enums
public enum Status {
INITIAL, PENDING, REJECTED, APPROVED, SHIPPED, DELIVERED, COMPLETE;
}
Voici une classe enveloppante appelée "Filter" que nous transmettrons à la méthode de filtrage du référentiel.
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();
}
}
Enfin, dans le référentiel, nous pouvons maintenant utiliser la classe Filter comme paramètre unique et faire en sorte que la requête traduise ce qui semble être un mélange de littéraux et d'expressions SpEL en un objet Status :
Le dépôt :
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);
}
Cela fonctionne parfaitement, mais pour une raison étrange que je n'ai pas encore trouvée, si vous activez le débogage SQL dans Hibernate et que vous activez la journalisation du binder, vous ne pourrez pas voir Hibernate lier cette expression aux variables de la requête.