Skip to content

Commit 8b83a53

Browse files
committed
HHH-18649 more work on TypedQueryReference in static metamodel
1 parent 79d3a34 commit 8b83a53

File tree

4 files changed

+73
-21
lines changed

4 files changed

+73
-21
lines changed

tooling/metamodel-generator/src/main/java/org/hibernate/processor/annotation/AnnotationMeta.java

Lines changed: 51 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,11 @@
1313
import org.hibernate.processor.util.Constants;
1414
import org.hibernate.processor.validation.ProcessorSessionFactory;
1515
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;
1619
import org.hibernate.query.sqm.tree.SqmStatement;
20+
import org.hibernate.query.sqm.tree.select.SqmSelectClause;
1721
import org.hibernate.query.sqm.tree.select.SqmSelectStatement;
1822

1923
import javax.lang.model.element.AnnotationMirror;
@@ -103,25 +107,56 @@ private void handleNamedQuery(AnnotationMirror mirror, boolean checkHql) {
103107
ProcessorSessionFactory.create( context.getProcessingEnvironment(),
104108
context.getEntityNameMappings(), context.getEnumTypesByValue() )
105109
);
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+
}
119133
}
120134
}
121135
}
122136
}
123137
}
124138

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+
125160
private static boolean isQueryMethodName(String name) {
126161
return name.length() >= 2
127162
&& name.charAt(0) == '#'
@@ -165,8 +200,9 @@ private void addAuxiliaryMembersForMirror(AnnotationMirror mirror, String prefix
165200
private NameMetaAttribute auxiliaryMember(AnnotationMirror mirror, String prefix, String name) {
166201
if ( !isJakartaDataStyle() && "QUERY_".equals(prefix) ) {
167202
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
170206
return new TypedMetaAttribute( this, name, prefix,
171207
resultClass == null ? JAVA_OBJECT : resultClass.getValue().toString(),
172208
"jakarta.persistence.TypedQueryReference" );

tooling/metamodel-generator/src/main/java/org/hibernate/processor/annotation/NameMetaAttribute.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ public String getAttributeNameDeclarationString() {
5454
.toString();
5555
}
5656

57-
private String fieldName() {
57+
String fieldName() {
5858
return nameToFieldName(name.charAt(0) == '#' ? name.substring(1) : name);
5959
}
6060

tooling/metamodel-generator/src/main/java/org/hibernate/processor/annotation/TypedMetaAttribute.java

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
* @author Gavin King
1313
*/
1414
class TypedMetaAttribute extends NameMetaAttribute {
15+
private final String prefix;
1516
private final String resultType;
1617
private final String referenceType;
1718

@@ -22,6 +23,7 @@ public TypedMetaAttribute(
2223
String resultType,
2324
String referenceType) {
2425
super( annotationMetaEntity, name, prefix );
26+
this.prefix = prefix;
2527
this.resultType = resultType;
2628
this.referenceType = referenceType;
2729
}
@@ -34,8 +36,13 @@ public boolean hasTypedAttribute() {
3436
@Override
3537
public String getAttributeDeclarationString() {
3638
final Metamodel entity = getHostingEntity();
37-
return new StringBuilder()
38-
.append("\n/**\n * @see ")
39+
final StringBuilder declaration = new StringBuilder();
40+
declaration
41+
.append("\n/**")
42+
.append("\n * The query named {@value ")
43+
.append(prefix)
44+
.append(fieldName())
45+
.append("}\n *\n * @see ")
3946
.append(entity.getQualifiedName())
4047
.append("\n **/\n")
4148
.append("public static volatile ")
@@ -45,8 +52,11 @@ public String getAttributeDeclarationString() {
4552
.append('>')
4653
.append(' ')
4754
.append('_')
48-
.append(nameToMethodName(getPropertyName()))
49-
.append(';')
50-
.toString();
55+
.append(nameToMethodName(getPropertyName()));
56+
if ( "QUERY_".equals(prefix) ) { //UGLY!
57+
declaration.append('_');
58+
}
59+
declaration.append(';');
60+
return declaration.toString();
5161
}
5262
}

tooling/metamodel-generator/src/test/java/org/hibernate/processor/test/namedquery/Book.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,12 @@
1111

1212
@Entity
1313
@NamedEntityGraph(name = "entityGraph")
14+
@NamedQuery(name="booksByTitle",
15+
query = "from Book where title = ?1")
16+
@NamedQuery(name="booksByTitleVerbose",
17+
query = "select book from Book book where book.title = ?1")
18+
@NamedQuery(name = "titlesWithIsbns",
19+
query = "select title, isbn from Book")
1420
@NamedQuery(name = "#findByTitle",
1521
query = "from Book where title like :titlePattern")
1622
@NamedQuery(name = "#findByTitleAndType",

0 commit comments

Comments
 (0)