HibernateUtils.java
/*
* Copyright 2016-present the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.data.jpa.provider;
import org.hibernate.query.NativeQuery;
import org.hibernate.query.Query;
import org.hibernate.query.SelectionQuery;
import org.jspecify.annotations.Nullable;
import org.springframework.data.util.Lazy;
/**
* Utility functions to work with Hibernate. Mostly using reflection to make sure common functionality can be executed
* against all the Hibernate version we support.
*
* @author Oliver Gierke
* @author Mark Paluch
* @author Jens Schauder
* @author Donghun Shin
* @author Greg Turnquist
* @author Oscar Fanchin
* @author Christoph Strobl
* @since 1.10.2
* @soundtrack Benny Greb - Soulfood (Live, https://www.youtube.com/watch?v=9_ErMa_CtSw)
*/
public abstract class HibernateUtils {
/**
* Deferred singleton.
*/
private static final Lazy<HibernateAdapter> HIBERNATE_ADAPTER = Lazy.of(HibernateAdapter::create);
private HibernateUtils() {}
/**
* Return the {@link SelectionQuery} the given query represents, or {@literal null} if it does not represent one.
*
* @since 4.2
*/
static @Nullable SelectionQuery<?> asSelectionQuery(jakarta.persistence.Query query) {
return getHibernateAdapter().asSelectionQuery(query);
}
/**
* Return the query string of the underlying native Hibernate query.
*
* @param query
* @return
*/
public @Nullable static String getHibernateQuery(Object query) {
HibernateAdapter adapter = getHibernateAdapter();
if (adapter.isSqmQuery(query)) {
String hql = adapter.getQueryString(query);
return queryStringOrFallback(query, hql);
}
if (adapter.isNamedSqmQuery(query)) {
String hql = adapter.getHqlString(query);
return queryStringOrFallback(query, hql);
}
if (adapter.isNamedNativeQuery(query)) {
return adapter.getSqlString(query);
}
if (query instanceof Query<?> hibernateQuery) {
return hibernateQuery.getQueryString();
}
throw new IllegalArgumentException("Don't know how to extract the query string from " + query);
}
private static String queryStringOrFallback(Object query, String hql) {
if (!hql.equals("<criteria>")) {
return hql;
}
return getHibernateAdapter().getSqmStatement(query);
}
public static boolean isNativeQuery(Object query) {
if (getHibernateAdapter().isSqmQuery(query) || getHibernateAdapter().isNamedSqmQuery(query)) {
return false;
}
if (query instanceof NativeQuery<?> || getHibernateAdapter().isNamedNativeQuery(query)) {
return true;
}
if (query instanceof jakarta.persistence.Query jpaQuery) {
try {
jpaQuery.unwrap(NativeQuery.class);
return true;
} catch (RuntimeException o_O) {
// Not a native Hibernate query.
}
}
return false;
}
private static HibernateAdapter getHibernateAdapter() {
return HIBERNATE_ADAPTER.get();
}
}