|
13 | 13 | import org.hibernate.processor.util.Constants;
|
14 | 14 | import org.hibernate.processor.validation.ProcessorSessionFactory;
|
15 | 15 | import org.hibernate.processor.validation.Validation;
|
| 16 | +import org.hibernate.query.criteria.JpaEntityJoin; |
| 17 | +import org.hibernate.query.criteria.JpaRoot; |
| 18 | +import org.hibernate.query.criteria.JpaSelection; |
16 | 19 | import org.hibernate.query.sqm.tree.SqmStatement;
|
| 20 | +import org.hibernate.query.sqm.tree.select.SqmSelectClause; |
17 | 21 | import org.hibernate.query.sqm.tree.select.SqmSelectStatement;
|
18 | 22 |
|
19 | 23 | import javax.lang.model.element.AnnotationMirror;
|
@@ -103,25 +107,56 @@ private void handleNamedQuery(AnnotationMirror mirror, boolean checkHql) {
|
103 | 107 | ProcessorSessionFactory.create( context.getProcessingEnvironment(),
|
104 | 108 | context.getEntityNameMappings(), context.getEnumTypesByValue() )
|
105 | 109 | );
|
106 |
| - if ( statement instanceof SqmSelectStatement |
107 |
| - && isQueryMethodName( name ) ) { |
108 |
| - putMember( name, |
109 |
| - new NamedQueryMethod( |
110 |
| - this, |
111 |
| - (SqmSelectStatement<?>) statement, |
112 |
| - name.substring(1), |
113 |
| - isRepository(), |
114 |
| - getSessionType(), |
115 |
| - getSessionVariableName(), |
116 |
| - context.addNonnullAnnotation() |
117 |
| - ) |
118 |
| - ); |
| 110 | + if ( statement instanceof SqmSelectStatement<?> selectStatement ) { |
| 111 | + if ( isQueryMethodName( name ) ) { |
| 112 | + putMember( name, |
| 113 | + new NamedQueryMethod( |
| 114 | + this, |
| 115 | + selectStatement, |
| 116 | + name.substring(1), |
| 117 | + isRepository(), |
| 118 | + getSessionType(), |
| 119 | + getSessionVariableName(), |
| 120 | + context.addNonnullAnnotation() |
| 121 | + ) |
| 122 | + ); |
| 123 | + } |
| 124 | + if ( !isJakartaDataStyle() |
| 125 | + && getAnnotationValue( mirror, "resultClass" ) == null ) { |
| 126 | + final String resultType = resultType( selectStatement ); |
| 127 | + if ( resultType != null ) { |
| 128 | + putMember( "QUERY_" + name, |
| 129 | + new TypedMetaAttribute( this, name, "QUERY_", resultType, |
| 130 | + "jakarta.persistence.TypedQueryReference" ) ); |
| 131 | + } |
| 132 | + } |
119 | 133 | }
|
120 | 134 | }
|
121 | 135 | }
|
122 | 136 | }
|
123 | 137 | }
|
124 | 138 |
|
| 139 | + private static @Nullable String resultType(SqmSelectStatement<?> selectStatement) { |
| 140 | + final JpaSelection<?> selection = selectStatement.getSelection(); |
| 141 | + if (selection == null) { |
| 142 | + return null; |
| 143 | + } |
| 144 | + else if (selection instanceof SqmSelectClause from) { |
| 145 | + return from.getSelectionItems().size() > 1 |
| 146 | + ? "Object[]" |
| 147 | + : from.getSelectionItems().get(0).getJavaTypeName(); |
| 148 | + } |
| 149 | + else if (selection instanceof JpaRoot<?> root) { |
| 150 | + return root.getModel().getTypeName(); |
| 151 | + } |
| 152 | + else if (selection instanceof JpaEntityJoin<?, ?> join) { |
| 153 | + return join.getModel().getTypeName(); |
| 154 | + } |
| 155 | + else { |
| 156 | + return selection.getJavaTypeName(); |
| 157 | + } |
| 158 | + } |
| 159 | + |
125 | 160 | private static boolean isQueryMethodName(String name) {
|
126 | 161 | return name.length() >= 2
|
127 | 162 | && name.charAt(0) == '#'
|
@@ -165,8 +200,9 @@ private void addAuxiliaryMembersForMirror(AnnotationMirror mirror, String prefix
|
165 | 200 | private NameMetaAttribute auxiliaryMember(AnnotationMirror mirror, String prefix, String name) {
|
166 | 201 | if ( !isJakartaDataStyle() && "QUERY_".equals(prefix) ) {
|
167 | 202 | final AnnotationValue resultClass = getAnnotationValue( mirror, "resultClass" );
|
168 |
| - //TODO: if there is no explicit result class, obtain the result class by |
169 |
| - // type-checking the query (this is allowed but not required by JPA) |
| 203 | + // if there is no explicit result class, we will infer it later by |
| 204 | + // type checking the query (this is allowed but not required by JPA) |
| 205 | + // and then we will replace this TypedMetaAttribute |
170 | 206 | return new TypedMetaAttribute( this, name, prefix,
|
171 | 207 | resultClass == null ? JAVA_OBJECT : resultClass.getValue().toString(),
|
172 | 208 | "jakarta.persistence.TypedQueryReference" );
|
|
0 commit comments