4 Jahre nach dem ersten Beitrag gibt es einige Entwicklungen. Mit Spring 4 und Hibernate 4 ist es nun möglich, Hibernate mit einem SpEL-Ausdruck zu "überlisten". 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 Filtermethode des Repositorys ü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();
}
}
Im Repository können wir nun die Klasse Filter als einzigen Parameter verwenden und die Abfrage dazu bringen, das, was wie eine Mischung aus Literalen und SpEL-Ausdrücken aussieht, in ein Statusobjekt zu übersetzen:
Das Endlager:
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 perfekt, aber aus irgendeinem seltsamen Grund, den ich noch nicht herausgefunden habe, wenn Sie SQL-Debugging in Hibernate aktivieren und die Binder-Protokollierung einschalten, können Sie nicht sehen, wie Hibernate diesen Ausdruck an Abfragevariablen bindet.