1
+ /**
2
+ * Copyright (c) 2025 Contributors to the Eclipse Foundation
3
+ *
4
+ * This program and the accompanying materials are made
5
+ * available under the terms of the Eclipse Public License 2.0
6
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
7
+ *
8
+ * SPDX-License-Identifier: EPL-2.0
9
+ */
10
+ package org .eclipse .hawkbit .repository .jpa ;
11
+
12
+ import java .lang .reflect .InvocationTargetException ;
13
+ import java .lang .reflect .Method ;
14
+ import java .util .List ;
15
+ import java .util .Map ;
16
+
17
+ import jakarta .persistence .TypedQuery ;
18
+
19
+ import lombok .NoArgsConstructor ;
20
+ import lombok .extern .slf4j .Slf4j ;
21
+ import org .hibernate .engine .spi .SessionFactoryImplementor ;
22
+ import org .hibernate .engine .spi .SharedSessionContractImplementor ;
23
+ import org .hibernate .metamodel .mapping .MappingModelExpressible ;
24
+ import org .hibernate .query .spi .QueryEngine ;
25
+ import org .hibernate .query .spi .QueryParameterImplementor ;
26
+ import org .hibernate .query .sqm .internal .QuerySqmImpl ;
27
+ import org .hibernate .query .sqm .internal .SqmUtil ;
28
+ import org .hibernate .query .sqm .spi .SqmParameterMappingModelResolutionAccess ;
29
+ import org .hibernate .query .sqm .sql .SqmTranslation ;
30
+ import org .hibernate .query .sqm .sql .SqmTranslator ;
31
+ import org .hibernate .query .sqm .sql .SqmTranslatorFactory ;
32
+ import org .hibernate .query .sqm .tree .SqmDmlStatement ;
33
+ import org .hibernate .query .sqm .tree .expression .SqmParameter ;
34
+ import org .hibernate .query .sqm .tree .select .SqmSelectStatement ;
35
+ import org .hibernate .sql .ast .SqlAstTranslatorFactory ;
36
+ import org .hibernate .sql .ast .tree .MutationStatement ;
37
+ import org .hibernate .sql .ast .tree .Statement ;
38
+ import org .hibernate .sql .ast .tree .select .SelectStatement ;
39
+ import org .hibernate .sql .exec .spi .JdbcParameterBindings ;
40
+ import org .hibernate .sql .exec .spi .JdbcParametersList ;
41
+
42
+ @ NoArgsConstructor (access = lombok .AccessLevel .PRIVATE )
43
+ @ Slf4j
44
+ public class Utils {
45
+
46
+ private static final Method getSqmTranslatorFactory ;
47
+
48
+ static {
49
+ Method method = null ;
50
+ try {
51
+ method = QueryEngine .class .getMethod ("getSqmTranslatorFactory" );
52
+ } catch (final NoSuchMethodException e ) {
53
+ log .warn ("Can't resolve getSqmTranslatorFactory method (Utils.toString won't work)" , e );
54
+ }
55
+ getSqmTranslatorFactory = method ;
56
+ }
57
+
58
+ public static String toSql (final TypedQuery <?> typedQuery ) {
59
+ if (getSqmTranslatorFactory == null ) {
60
+ throw new UnsupportedOperationException ("SqmTranslatorFactory resolver is not available" );
61
+ }
62
+
63
+ final QuerySqmImpl <?> hqlQuery = typedQuery .unwrap (QuerySqmImpl .class );
64
+ final SessionFactoryImplementor factory = hqlQuery .getSessionFactory ();
65
+ final SharedSessionContractImplementor session = hqlQuery .getSession ();
66
+ final SessionFactoryImplementor sessionFactory = session .getFactory ();
67
+
68
+ final SqmTranslatorFactory sqmTranslatorFactory ;
69
+ try {
70
+ sqmTranslatorFactory = (SqmTranslatorFactory ) getSqmTranslatorFactory .invoke (factory .getQueryEngine ());
71
+ } catch (final IllegalAccessException | InvocationTargetException e ) {
72
+ throw new UnsupportedOperationException ("Can't create SqmTranslatorFactory" , e );
73
+ }
74
+
75
+ final SqmTranslator <? extends Statement > sqmSelectTranslator =
76
+ hqlQuery .getSqmStatement () instanceof SqmSelectStatement <?> selectStatement
77
+ ? sqmTranslatorFactory .createSelectTranslator (selectStatement ,
78
+ hqlQuery .getQueryOptions (), hqlQuery .getDomainParameterXref (), hqlQuery .getQueryParameterBindings (),
79
+ hqlQuery .getLoadQueryInfluencers (), sessionFactory , false )
80
+ : sqmTranslatorFactory .createMutationTranslator ((SqmDmlStatement <?>) hqlQuery .getSqmStatement (),
81
+ hqlQuery .getQueryOptions (), hqlQuery .getDomainParameterXref (), hqlQuery .getQueryParameterBindings (),
82
+ hqlQuery .getLoadQueryInfluencers (), sessionFactory );
83
+
84
+ final SqmTranslation <? extends Statement > sqmTranslation = sqmSelectTranslator .translate ();
85
+ final SqlAstTranslatorFactory sqlAstTranslatorFactory = factory .getJdbcServices ().getJdbcEnvironment ().getSqlAstTranslatorFactory ();
86
+ final Map <QueryParameterImplementor <?>, Map <SqmParameter <?>, List <JdbcParametersList >>> jdbcParamsXref = SqmUtil .generateJdbcParamsXref (
87
+ hqlQuery .getDomainParameterXref (), sqmTranslation ::getJdbcParamsBySqmParam );
88
+
89
+ final JdbcParameterBindings jdbcParameterBindings = SqmUtil .createJdbcParameterBindings (hqlQuery .getQueryParameterBindings (),
90
+ hqlQuery .getDomainParameterXref (), jdbcParamsXref , factory .getRuntimeMetamodels ().getMappingMetamodel (),
91
+ sqmSelectTranslator .getFromClauseAccess ()::findTableGroup , new SqmParameterMappingModelResolutionAccess () {
92
+
93
+ @ Override
94
+ @ SuppressWarnings ("unchecked" )
95
+ public <T > MappingModelExpressible <T > getResolvedMappingModelType (final SqmParameter <T > parameter ) {
96
+ return (MappingModelExpressible <T >) sqmTranslation .getSqmParameterMappingModelTypeResolutions ().get (parameter );
97
+ }
98
+ }, hqlQuery .getSession ());
99
+ return (sqmTranslation .getSqlAst () instanceof SelectStatement selectStatement
100
+ ? sqlAstTranslatorFactory .buildSelectTranslator (factory , selectStatement )
101
+ .translate (jdbcParameterBindings , hqlQuery .getQueryOptions ())
102
+ : sqlAstTranslatorFactory .buildMutationTranslator (factory , (MutationStatement ) sqmTranslation .getSqlAst ())
103
+ .translate (jdbcParameterBindings , hqlQuery .getQueryOptions ()))
104
+ .getSqlString ();
105
+ }
106
+ }
0 commit comments