Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
import javax.lang.model.element.AnnotationValue;
import javax.lang.model.element.Element;
import javax.lang.model.element.ExecutableElement;
import javax.lang.model.element.ModuleElement;
import javax.lang.model.element.TypeElement;
import javax.lang.model.type.DeclaredType;
import javax.lang.model.type.TypeKind;
Expand All @@ -34,6 +35,7 @@
import static java.lang.Boolean.parseBoolean;
import static java.util.Collections.emptyList;
import static org.hibernate.internal.util.collections.ArrayHelper.EMPTY_STRING_ARRAY;
import static org.hibernate.processor.validation.ProcessorSessionFactory.findEntityByUnqualifiedName;

/**
* @author Max Andersen
Expand Down Expand Up @@ -505,4 +507,26 @@ public Map<String,Set<String>> getEnumTypesByValue() {
public void addEnumValue(String type, String value) {
enumTypesByValue.computeIfAbsent( value, s -> new TreeSet<>() ).add( type );
}

@Nullable
public TypeElement entityType(String entityName) {
final Elements elementUtils = getElementUtils();
final String qualifiedName = qualifiedNameForEntityName(entityName);
if ( qualifiedName != null ) {
return elementUtils.getTypeElement(qualifiedName);
}
TypeElement symbol =
findEntityByUnqualifiedName( entityName,
elementUtils.getModuleElement("") );
if ( symbol != null ) {
return symbol;
}
for ( ModuleElement module : elementUtils.getAllModuleElements() ) {
symbol = findEntityByUnqualifiedName( entityName, module );
if ( symbol != null ) {
return symbol;
}
}
return null;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,7 @@
import org.hibernate.processor.util.Constants;
import org.hibernate.processor.validation.ProcessorSessionFactory;
import org.hibernate.processor.validation.Validation;
import org.hibernate.query.criteria.JpaEntityJoin;
import org.hibernate.query.criteria.JpaRoot;
import org.hibernate.query.criteria.JpaSelection;
import org.hibernate.query.sqm.tree.SqmStatement;
import org.hibernate.query.sqm.tree.select.SqmSelectClause;
import org.hibernate.query.sqm.tree.select.SqmSelectStatement;

import javax.lang.model.element.AnnotationMirror;
Expand All @@ -33,6 +29,7 @@
import static org.hibernate.processor.util.TypeUtils.containsAnnotation;
import static org.hibernate.processor.util.TypeUtils.getAnnotationMirror;
import static org.hibernate.processor.util.TypeUtils.getAnnotationValue;
import static org.hibernate.processor.util.SqmTypeUtils.resultType;

public abstract class AnnotationMeta implements Metamodel {

Expand Down Expand Up @@ -126,7 +123,7 @@ private void handleNamedQuery(AnnotationMirror mirror, boolean checkHql) {
);
}
if ( getAnnotationValue( mirror, "resultClass" ) == null ) {
final String resultType = resultType( selectStatement );
final String resultType = resultType( selectStatement, context );
if ( resultType != null ) {
putMember( "QUERY_" + name,
new TypedMetaAttribute( this, name, "QUERY_", resultType,
Expand All @@ -139,27 +136,6 @@ private void handleNamedQuery(AnnotationMirror mirror, boolean checkHql) {
}
}

private static @Nullable String resultType(SqmSelectStatement<?> selectStatement) {
final JpaSelection<?> selection = selectStatement.getSelection();
if (selection == null) {
return null;
}
else if (selection instanceof SqmSelectClause from) {
return from.getSelectionItems().size() > 1
? "Object[]"
: from.getSelectionItems().get(0).getJavaTypeName();
}
else if (selection instanceof JpaRoot<?> root) {
return root.getModel().getTypeName();
}
else if (selection instanceof JpaEntityJoin<?, ?> join) {
return join.getModel().getTypeName();
}
else {
return selection.getJavaTypeName();
}
}

private static boolean isQueryMethodName(String name) {
return name.length() >= 2
&& name.charAt(0) == '#'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,24 +5,17 @@
package org.hibernate.processor.annotation;

import org.checkerframework.checker.nullness.qual.Nullable;
import org.hibernate.processor.Context;
import org.hibernate.processor.model.MetaAttribute;
import org.hibernate.processor.model.Metamodel;
import org.hibernate.processor.util.Constants;
import org.hibernate.query.sqm.SqmExpressible;
import org.hibernate.query.sqm.tree.expression.SqmParameter;
import org.hibernate.query.sqm.tree.select.SqmSelectStatement;
import org.hibernate.query.sqm.tree.select.SqmSelectableNode;
import org.hibernate.type.descriptor.java.JavaType;

import javax.lang.model.element.ModuleElement;
import javax.lang.model.element.TypeElement;
import javax.lang.model.util.Elements;
import java.util.List;
import java.util.TreeSet;

import static org.hibernate.processor.util.StringUtil.nameToFieldName;
import static org.hibernate.processor.validation.ProcessorSessionFactory.findEntityByUnqualifiedName;
import static org.hibernate.processor.util.SqmTypeUtils.resultType;

/**
* @author Gavin King
Expand Down Expand Up @@ -96,27 +89,6 @@ private String fieldName() {
return "QUERY_" + nameToFieldName(name);
}

private String returnType() {
final JavaType<?> javaType = select.getSelection().getJavaTypeDescriptor();
if ( javaType != null ) {
return javaType.getTypeName();
}
else {
final List<SqmSelectableNode<?>> items =
select.getQuerySpec().getSelectClause().getSelectionItems();
final SqmExpressible<?> expressible;
if ( items.size() == 1 && ( expressible = items.get( 0 ).getExpressible() ) != null ) {
final String typeName = expressible.getTypeName();
final TypeElement entityType = entityType( typeName );
return entityType == null ? typeName : entityType.getQualifiedName().toString();

}
else {
return "Object[]";
}
}
}

void notNull(StringBuilder declaration) {
if ( addNonnullAnnotation ) {
declaration
Expand Down Expand Up @@ -149,7 +121,7 @@ private void returnType(StringBuilder declaration) {
declaration
.append(annotationMeta.importType(Constants.LIST))
.append('<')
.append(annotationMeta.importType(returnType()))
.append( annotationMeta.importType( resultType( select, annotationMeta.getContext() ) ) )
.append("> ")
.append(name);
if ( reactive ) {
Expand Down Expand Up @@ -193,28 +165,6 @@ private String parameterType(SqmParameter<?> param) {
return "unknown".equals(paramType) ? "Object" : annotationMeta.importType(paramType);
}

private @Nullable TypeElement entityType(String entityName) {
final Context context = annotationMeta.getContext();
final Elements elementUtils = context.getElementUtils();
final String qualifiedName = context.qualifiedNameForEntityName(entityName);
if ( qualifiedName != null ) {
return elementUtils.getTypeElement(qualifiedName);
}
TypeElement symbol =
findEntityByUnqualifiedName( entityName,
elementUtils.getModuleElement("") );
if ( symbol != null ) {
return symbol;
}
for ( ModuleElement module : elementUtils.getAllModuleElements() ) {
symbol = findEntityByUnqualifiedName( entityName, module );
if ( symbol != null ) {
return symbol;
}
}
return null;
}

@Override
public String getAttributeNameDeclarationString() {
throw new UnsupportedOperationException("operation not supported");
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
/*
* SPDX-License-Identifier: LGPL-2.1-or-later
* Copyright Red Hat Inc. and Hibernate Authors
*/
package org.hibernate.processor.util;

import org.hibernate.processor.Context;
import org.hibernate.query.sqm.SqmExpressible;
import org.hibernate.query.sqm.tree.select.SqmSelectStatement;
import org.hibernate.query.sqm.tree.select.SqmSelectableNode;

import javax.lang.model.element.TypeElement;
import java.util.List;

public final class SqmTypeUtils {
private SqmTypeUtils() {
}

public static String resultType(SqmSelectStatement<?> selectStatement, Context context) {
final String javaTypeName = selectStatement.getSelection().getJavaTypeName();
if ( javaTypeName != null ) {
return javaTypeName;
}
else {
final List<SqmSelectableNode<?>> items =
selectStatement.getQuerySpec().getSelectClause().getSelectionItems();
final SqmExpressible<?> expressible;
if ( items.size() == 1 && (expressible = items.get( 0 ).getExpressible()) != null ) {
final String typeName = expressible.getTypeName();
final TypeElement entityType = context.entityType( typeName );
return entityType == null ? typeName : entityType.getQualifiedName().toString();
}
else {
return "Object[]";
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
/*
* SPDX-License-Identifier: LGPL-2.1-or-later
* Copyright Red Hat Inc. and Hibernate Authors
*/
package org.hibernate.processor.test.namedentity;

import jakarta.persistence.Entity;
import jakarta.persistence.Id;
import jakarta.persistence.NamedQuery;

@Entity(name = "Liber")
@NamedQuery(name = "findAllBooks", query = "from Liber")
public class Book {
@Id
private Integer id;

private String name;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
/*
* SPDX-License-Identifier: LGPL-2.1-or-later
* Copyright Red Hat Inc. and Hibernate Authors
*/
package org.hibernate.processor.test.namedentity;

import jakarta.persistence.TypedQueryReference;
import org.hibernate.processor.test.util.CompilationTest;
import org.hibernate.processor.test.util.WithClasses;
import org.junit.Test;

import java.lang.reflect.Field;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;

import static org.hibernate.processor.test.util.TestUtil.assertMetamodelClassGeneratedFor;
import static org.hibernate.processor.test.util.TestUtil.assertPresenceOfFieldInMetamodelFor;
import static org.hibernate.processor.test.util.TestUtil.getFieldFromMetamodelFor;
import static org.hibernate.processor.test.util.TestUtil.getMetaModelSourceAsString;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;

public class NamedEntityTest extends CompilationTest {

@Test
@WithClasses(Book.class)
public void test() {
System.out.println( getMetaModelSourceAsString( Book.class ) );

assertMetamodelClassGeneratedFor( Book.class );

assertPresenceOfFieldInMetamodelFor( Book.class, "QUERY_FIND_ALL_BOOKS" );
final Field field = getFieldFromMetamodelFor( Book.class, "_findAllBooks_" );
assertEquals( TypedQueryReference.class, field.getType() );
final Type genericType = field.getGenericType();
assertTrue( genericType instanceof ParameterizedType );
final ParameterizedType parameterizedType = (ParameterizedType) genericType;
assertEquals( Book.class, parameterizedType.getActualTypeArguments()[0] );
}
}
Loading