diff --git a/src/main/java/org/omnifaces/persistence/JPA.java b/src/main/java/org/omnifaces/persistence/JPA.java index c03b74f..e749ff6 100644 --- a/src/main/java/org/omnifaces/persistence/JPA.java +++ b/src/main/java/org/omnifaces/persistence/JPA.java @@ -16,6 +16,8 @@ import static java.util.stream.Collectors.toList; import static org.omnifaces.persistence.Database.POSTGRESQL; import static org.omnifaces.persistence.Provider.HIBERNATE; +import static org.omnifaces.utils.reflect.Reflections.findClass; +import static org.omnifaces.utils.reflect.Reflections.invokeMethod; import static org.omnifaces.utils.stream.Collectors.toMap; import static org.omnifaces.utils.stream.Streams.stream; @@ -77,6 +79,9 @@ public final class JPA { public static final String QUERY_HINT_CACHE_RETRIEVE_MODE = "jakarta.persistence.cache.retrieveMode"; // USE | BYPASS public static final String PROPERTY_VALIDATION_MODE = "jakarta.persistence.validation.mode"; // AUTO | CALLBACK | NONE + // Private constants ------------------------------------------------------------------------------------------------------------------ + + private static final Optional> HIBERNATE_6_6_0_JPA_EXPRESSION = findClass("org.hibernate.query.criteria.JpaExpression"); // Constructors ----------------------------------------------------------------------------------------------------------------------- @@ -353,8 +358,16 @@ public static Expression concat(CriteriaBuilder builder, Object... expre */ @SuppressWarnings("unchecked") public static Expression castAsString(CriteriaBuilder builder, Expression expression) { + + // NOTE: Improvement for all providers is expected in JPA 3.2 with new Expression#cast() API. + if (Provider.is(HIBERNATE)) { - return expression.as(String.class); + if (HIBERNATE_6_6_0_JPA_EXPRESSION.isPresent() && HIBERNATE_6_6_0_JPA_EXPRESSION.get().isInstance(expression)) { + return invokeMethod(expression, "cast", String.class); // https://hibernate.atlassian.net/browse/HHH-18710 + } + else { + return expression.as(String.class); + } } // EclipseLink and OpenJPA have a broken Expression#as() implementation, need to delegate to DB specific function.