diff --git a/pom.xml b/pom.xml
index a40fa7b7..84ded526 100644
--- a/pom.xml
+++ b/pom.xml
@@ -23,8 +23,8 @@
 		17
 		17
 		UTF-8
-		3.0.0
-		2022.0.0
+		3.4.1
+		2024.1.1
 		4.1.4
 		2.3.2
 		1.18.24
diff --git a/rsql-common/pom.xml b/rsql-common/pom.xml
index 4424ab81..a1c347e5 100644
--- a/rsql-common/pom.xml
+++ b/rsql-common/pom.xml
@@ -34,8 +34,8 @@
 		
 		
 			io.hypersistence
-			hypersistence-utils-hibernate-62
-			3.5.1
+			hypersistence-utils-hibernate-63
+			3.9.0
 			test
 		
 		
diff --git a/rsql-common/src/main/java/io/github/perplexhub/rsql/RSQLVisitorBase.java b/rsql-common/src/main/java/io/github/perplexhub/rsql/RSQLVisitorBase.java
index 8fe8eda6..2a06df1d 100644
--- a/rsql-common/src/main/java/io/github/perplexhub/rsql/RSQLVisitorBase.java
+++ b/rsql-common/src/main/java/io/github/perplexhub/rsql/RSQLVisitorBase.java
@@ -1,6 +1,7 @@
 package io.github.perplexhub.rsql;
 
 import java.lang.reflect.*;
+import java.sql.Timestamp;
 import java.time.*;
 import java.time.format.DateTimeParseException;
 import java.util.*;
@@ -13,6 +14,7 @@
 import jakarta.persistence.metamodel.PluralAttribute;
 
 import lombok.Getter;
+import org.hibernate.metamodel.model.domain.ManagedDomainType;
 import org.springframework.core.convert.ConversionFailedException;
 import org.springframework.core.convert.support.ConfigurableConversionService;
 import org.springframework.orm.jpa.vendor.Database;
@@ -52,6 +54,15 @@ public static Database getDatabase(EntityManager entityManager) {
 		return entityManagerDatabase.get(entityManager);
 	}
 
+	public static  Attribute super T, ?> getAttribute(String property, ManagedType classMetadata) {
+		// W/A found here: https://hibernate.atlassian.net/browse/HHH-18569
+		// breaking change on hibernate side: https://github.com/hibernate/hibernate-orm/pull/6924#discussion_r1250474422
+		if (classMetadata instanceof ManagedDomainType managedDomainType) {
+			return managedDomainType.findSubTypesAttribute(property);
+		}
+		return classMetadata.getAttribute(property);
+	}
+
 	protected abstract Map getPropertyPathMapper();
 
 	public Map, Map> getPropertyRemapping() {
@@ -71,6 +82,9 @@ protected Object convert(String source, Class targetType) {
 				object = UUID.fromString(source);
 			} else if (targetType.equals(Date.class) || targetType.equals(java.sql.Date.class)) {
 				object = java.sql.Date.valueOf(LocalDate.parse(source));
+			} else if (targetType.equals(Timestamp.class)) {
+				Date date = java.sql.Date.valueOf(LocalDate.parse(source));
+				return new Timestamp(date.getTime());
 			} else if (targetType.equals(LocalDate.class)) {
 				object = LocalDate.parse(source);
 			} else if (targetType.equals(LocalDateTime.class)) {
@@ -158,10 +172,10 @@ protected String mapProperty(String selector, Class> entityClass) {
 
 	protected  Class> findPropertyType(String property, ManagedType classMetadata) {
 		Class> propertyType = null;
-		if (classMetadata.getAttribute(property).isCollection()) {
-			propertyType = ((PluralAttribute) classMetadata.getAttribute(property)).getBindableJavaType();
+		if (getAttribute(property, classMetadata).isCollection()) {
+			propertyType = ((PluralAttribute) getAttribute(property, classMetadata)).getBindableJavaType();
 		} else {
-			propertyType = classMetadata.getAttribute(property).getJavaType();
+			propertyType = getAttribute(property, classMetadata).getJavaType();
 		}
 		return propertyType;
 	}
@@ -217,7 +231,7 @@ protected  ManagedType getManagedElementCollectionType(String mappedProper
 
 	protected  boolean hasPropertyName(String property, ManagedType classMetadata) {
 		try {
-			return classMetadata.getAttribute(property) != null;
+			return getAttribute(property, classMetadata) != null;
 		} catch (IllegalArgumentException e) {
 			return false;
 		}
@@ -238,30 +252,30 @@ protected static Class getElementCollectionGenericType(Class type, Attribute att
 	}
 
 	protected  boolean isEmbeddedType(String property, ManagedType classMetadata) {
-		return classMetadata.getAttribute(property).getPersistentAttributeType() == PersistentAttributeType.EMBEDDED;
+		return getAttribute(property, classMetadata).getPersistentAttributeType() == PersistentAttributeType.EMBEDDED;
 	}
 
 	protected  boolean isElementCollectionType(String property, ManagedType classMetadata) {
-		return classMetadata.getAttribute(property).getPersistentAttributeType() == PersistentAttributeType.ELEMENT_COLLECTION;
+		return getAttribute(property, classMetadata).getPersistentAttributeType() == PersistentAttributeType.ELEMENT_COLLECTION;
 	}
 
 	protected  boolean isAssociationType(String property, ManagedType classMetadata) {
-		return classMetadata.getAttribute(property).isAssociation();
+		return getAttribute(property, classMetadata).isAssociation();
 	}
 
 	protected  boolean isOneToOneAssociationType(String property, ManagedType classMetadata) {
-		return classMetadata.getAttribute(property).isAssociation()
-				&& PersistentAttributeType.ONE_TO_ONE == classMetadata.getAttribute(property).getPersistentAttributeType();
+		return getAttribute(property, classMetadata).isAssociation()
+				&& PersistentAttributeType.ONE_TO_ONE == getAttribute(property, classMetadata).getPersistentAttributeType();
 	}
 
 	protected  boolean isOneToManyAssociationType(String property, ManagedType classMetadata) {
-		return classMetadata.getAttribute(property).isAssociation()
-				&& PersistentAttributeType.ONE_TO_MANY == classMetadata.getAttribute(property).getPersistentAttributeType();
+		return getAttribute(property, classMetadata).isAssociation()
+				&& PersistentAttributeType.ONE_TO_MANY == getAttribute(property, classMetadata).getPersistentAttributeType();
 	}
 
 	protected  boolean isManyToManyAssociationType(String property, ManagedType classMetadata) {
-		return classMetadata.getAttribute(property).isAssociation()
-				&& PersistentAttributeType.MANY_TO_MANY == classMetadata.getAttribute(property).getPersistentAttributeType();
+		return getAttribute(property, classMetadata).isAssociation()
+				&& PersistentAttributeType.MANY_TO_MANY == getAttribute(property, classMetadata).getPersistentAttributeType();
 	}
 
 	static {
diff --git a/rsql-jpa/pom.xml b/rsql-jpa/pom.xml
index d39c81e0..a0f34862 100644
--- a/rsql-jpa/pom.xml
+++ b/rsql-jpa/pom.xml
@@ -54,8 +54,8 @@
 		
 		
 			io.hypersistence
-			hypersistence-utils-hibernate-60
-			3.5.2
+			hypersistence-utils-hibernate-63
+			3.9.0
 			test
 		
 		
diff --git a/rsql-jpa/src/main/java/io/github/perplexhub/rsql/RSQLJPAPredicateConverter.java b/rsql-jpa/src/main/java/io/github/perplexhub/rsql/RSQLJPAPredicateConverter.java
index 37f706e1..20414076 100644
--- a/rsql-jpa/src/main/java/io/github/perplexhub/rsql/RSQLJPAPredicateConverter.java
+++ b/rsql-jpa/src/main/java/io/github/perplexhub/rsql/RSQLJPAPredicateConverter.java
@@ -20,6 +20,7 @@
 import cz.jirutka.rsql.parser.ast.OrNode;
 import lombok.Getter;
 import lombok.extern.slf4j.Slf4j;
+import org.hibernate.query.criteria.JpaExpression;
 
 @Slf4j
 @SuppressWarnings({ "rawtypes", "unchecked" })
@@ -81,7 +82,6 @@ private RSQLJPAContext findPropertyPathInternal(String propertyPath, Path startR
 		Attribute, ?> attribute = null;
 		String resolvedPropertyPath = firstTry? mapPropertyPath(propertyPath) : propertyPath;
 		String[] properties = mapPropertyPath(resolvedPropertyPath).split("\\.");
-
 		for (int i = 0, propertiesLength = properties.length; i < propertiesLength; i++) {
 			String property = properties[i];
 			String mappedProperty = mapProperty(property, classMetadata.getJavaType());
@@ -138,14 +138,14 @@ private RSQLJPAContext findPropertyPathInternal(String propertyPath, Path startR
 			  	}
 			} else if (isElementCollectionType(mappedProperty, classMetadata)) {
 					String previousClass = classMetadata.getJavaType().getName();
-					attribute = classMetadata.getAttribute(property);
+					attribute = RSQLVisitorBase.getAttribute(property, classMetadata);
 					classMetadata = getManagedElementCollectionType(mappedProperty, classMetadata);
 					String keyJoin = getKeyJoin(root, mappedProperty);
 					log.debug("Create a element collection join between [{}] and [{}] using key [{}]", previousClass, classMetadata.getJavaType().getName(), keyJoin);
 					root = join(keyJoin, root, mappedProperty);
 				} else if (JsonbSupport.isJsonType(mappedProperty, classMetadata)) {
 					root = root.get(mappedProperty);
-					attribute = classMetadata.getAttribute(mappedProperty);
+					attribute = RSQLVisitorBase.getAttribute(mappedProperty, classMetadata);
 					break;
 				} else {
 					log.debug("Create property path for type [{}] property [{}]", classMetadata.getJavaType().getName(), mappedProperty);
@@ -156,7 +156,7 @@ private RSQLJPAContext findPropertyPathInternal(String propertyPath, Path startR
 						type = embeddedType;
 						classMetadata = getManagedType(embeddedType);
 					} else {
-						attribute = classMetadata.getAttribute(property);
+						attribute = RSQLVisitorBase.getAttribute(property, classMetadata);
 					}
 				}
 			}
@@ -244,7 +244,13 @@ private ResolvedExpression resolveExpression(ComparisonNode node, From root, Sel
 					ComparisonNode jsonbNode = node.withSelector(jsonbPath);
 					return JsonbSupport.jsonbPathExistsExpression(builder, jsonbNode, path);
 				} else {
-					return ResolvedExpression.ofPath(path.as(String.class), String.class);
+					final Expression expression;
+					if (path instanceof JpaExpression jpaExpression) {
+						expression = jpaExpression.cast(String.class);
+					} else {
+						expression = path.as(String.class);
+					}
+					return ResolvedExpression.ofPath(expression, String.class);
 				}
 			} else {
 				if (attribute != null
diff --git a/rsql-jpa/src/main/java/io/github/perplexhub/rsql/SortUtils.java b/rsql-jpa/src/main/java/io/github/perplexhub/rsql/SortUtils.java
index 8f8ce8c3..46d4f6e3 100644
--- a/rsql-jpa/src/main/java/io/github/perplexhub/rsql/SortUtils.java
+++ b/rsql-jpa/src/main/java/io/github/perplexhub/rsql/SortUtils.java
@@ -13,6 +13,7 @@
 import jakarta.persistence.criteria.Order;
 import jakarta.persistence.criteria.Root;
 
+import org.hibernate.query.criteria.JpaExpression;
 import org.springframework.lang.Nullable;
 import org.springframework.util.StringUtils;
 
@@ -63,16 +64,16 @@ private static Order sortToJpaOrder(final String[] parts, final SortSupport sort
                         sortSupport.getJoinHints(), sortSupport.getProcedureWhiteList(),
                         sortSupport.getProcedureBlackList());
 
+        final boolean ic = parts.length > 2 && "ic".equalsIgnoreCase(parts[2]);
         Expression> propertyExpression = selector.getExpression((string, builder) ->{
             final RSQLJPAContext rsqljpaContext = converter.findPropertyPath(string, root);
             final boolean isJson = JsonbSupport.isJsonType(rsqljpaContext.getAttribute());
             return isJson
-                    ? sortExpressionOfJson(rsqljpaContext, string, sortSupport.getPropertyPathMapper(), builder)
+                    ? sortExpressionOfJson(rsqljpaContext, string, sortSupport.getPropertyPathMapper(), builder, ic)
                     : rsqljpaContext.getPath();
         });
 
-        if (parts.length > 2 && "ic".equalsIgnoreCase(parts[2])
-            && String.class.isAssignableFrom(propertyExpression.getJavaType())) {
+        if (ic && String.class.isAssignableFrom(propertyExpression.getJavaType())) {
             propertyExpression = cb.lower(propertyExpression.as(String.class));
         }
 
@@ -92,7 +93,8 @@ private static Order sortToJpaOrder(final String[] parts, final SortSupport sort
     private static Expression> sortExpressionOfJson(RSQLJPAContext context,
                                                       String property,
                                                       Map mapping,
-                                                      CriteriaBuilder builder) {
+                                                      CriteriaBuilder builder,
+                                                      boolean ic) {
         String path = PathUtils.expectBestMapping(property, mapping);
         String jsonbSelector = JsonbSupport.jsonPathOfSelector(context.getAttribute(), path);
         if(jsonbSelector.contains(".")) {
@@ -102,7 +104,11 @@ private static Expression> sortExpressionOfJson(RSQLJPAContext context,
                     .skip(1) // skip root
                     .map(builder::literal)
                     .forEach(args::add);
-            return builder.function("jsonb_extract_path", String.class, args.toArray(Expression[]::new));
+            Expression> expression = builder.function("jsonb_extract_path", Object.class, args.toArray(Expression[]::new));
+            if (ic && expression instanceof JpaExpression> jpaExpression) {
+                expression = jpaExpression.cast(String.class);
+            }
+            return expression;
         } else {
             return context.getPath().as(String.class);
         }
diff --git a/rsql-jpa/src/main/java/io/github/perplexhub/rsql/jsonb/JsonbSupport.java b/rsql-jpa/src/main/java/io/github/perplexhub/rsql/jsonb/JsonbSupport.java
index b27eddc4..4c0e7be3 100644
--- a/rsql-jpa/src/main/java/io/github/perplexhub/rsql/jsonb/JsonbSupport.java
+++ b/rsql-jpa/src/main/java/io/github/perplexhub/rsql/jsonb/JsonbSupport.java
@@ -91,7 +91,7 @@ && isJsonColumn(attribute)
      * @return true if the attribute is a jsonb attribute
      */
     public static boolean isJsonType(String mappedProperty, ManagedType> classMetadata) {
-        return Optional.ofNullable(classMetadata.getAttribute(mappedProperty))
+        return Optional.ofNullable(RSQLVisitorBase.getAttribute(mappedProperty, classMetadata))
                 .map(JsonbSupport::isJsonType)
                 .orElse(false);
     }
diff --git a/rsql-jpa/src/test/java/io/github/perplexhub/rsql/RSQLJPASupportTest.java b/rsql-jpa/src/test/java/io/github/perplexhub/rsql/RSQLJPASupportTest.java
index c3bc94cc..4c39ec19 100644
--- a/rsql-jpa/src/test/java/io/github/perplexhub/rsql/RSQLJPASupportTest.java
+++ b/rsql-jpa/src/test/java/io/github/perplexhub/rsql/RSQLJPASupportTest.java
@@ -9,8 +9,10 @@
 import static org.junit.jupiter.api.Assertions.assertEquals;
 import static org.junit.jupiter.api.Assertions.assertThrows;
 
+import java.sql.Timestamp;
 import java.text.ParseException;
 import java.text.SimpleDateFormat;
+import java.time.LocalDate;
 import java.time.OffsetDateTime;
 import java.time.ZoneOffset;
 import java.util.*;
@@ -764,9 +766,9 @@ final void testBetweenDate() {
 	@Test
 	final void testBetweenDateTime() {
 		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
-		RSQLJPASupport.addConverter(Date.class, s -> {
+		RSQLJPASupport.addConverter(Timestamp.class, s -> {
 			try {
-				return sdf.parse(s);
+				return new Timestamp(sdf.parse(s).getTime());
 			} catch (ParseException e) {
 				return null;
 			}
diff --git a/rsql-querydsl-spring-boot-starter/src/test/java/io/github/perplexhub/rsql/Application.java b/rsql-querydsl-spring-boot-starter/src/test/java/io/github/perplexhub/rsql/Application.java
index 5e9dba1e..f9f13864 100644
--- a/rsql-querydsl-spring-boot-starter/src/test/java/io/github/perplexhub/rsql/Application.java
+++ b/rsql-querydsl-spring-boot-starter/src/test/java/io/github/perplexhub/rsql/Application.java
@@ -1,5 +1,6 @@
 package io.github.perplexhub.rsql;
 
+import java.sql.Timestamp;
 import java.text.SimpleDateFormat;
 import java.util.Date;
 
@@ -23,9 +24,9 @@ public static void main(String[] args) throws Exception {
 	@Bean
 	public Object rsqlConfiguration(RSQLCommonSupport rsqlCommonSupport) {
 		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
-		RSQLCommonSupport.addConverter(Date.class, s -> {
+		RSQLCommonSupport.addConverter(Timestamp.class, s -> {
 			try {
-				return sdf.parse(s);
+				return new Timestamp(sdf.parse(s).getTime());
 			} catch (Exception e) {
 				return null;
 			}