HHH-18137 private fields inherited from supertypes in HibernateProcessor

Elements.getAllMembers() does not do what it appears to do

Signed-off-by: Gavin King <gavin@hibernate.org>
This commit is contained in:
Gavin King 2024-05-20 22:04:58 +02:00
parent 2619df6c7f
commit 5a89a31e63
6 changed files with 101 additions and 3 deletions

View File

@ -17,7 +17,11 @@ import javax.annotation.processing.ProcessingEnvironment;
import javax.lang.model.element.AnnotationMirror; import javax.lang.model.element.AnnotationMirror;
import javax.lang.model.element.AnnotationValue; import javax.lang.model.element.AnnotationValue;
import javax.lang.model.element.Element; import javax.lang.model.element.Element;
import javax.lang.model.element.ExecutableElement;
import javax.lang.model.element.TypeElement; import javax.lang.model.element.TypeElement;
import javax.lang.model.type.DeclaredType;
import javax.lang.model.type.TypeKind;
import javax.lang.model.type.TypeMirror;
import javax.lang.model.util.Elements; import javax.lang.model.util.Elements;
import javax.lang.model.util.Types; import javax.lang.model.util.Types;
import javax.tools.Diagnostic; import javax.tools.Diagnostic;
@ -448,4 +452,35 @@ public final class Context {
|| pattern.startsWith("*") && name.endsWith( pattern.substring(1) ) || pattern.startsWith("*") && name.endsWith( pattern.substring(1) )
|| pattern.startsWith("*") && pattern.endsWith("*") && name.contains( pattern.substring(1, pattern.length()-1) ); || pattern.startsWith("*") && pattern.endsWith("*") && name.contains( pattern.substring(1, pattern.length()-1) );
} }
public List<Element> getAllMembers(TypeElement type) {
final List<? extends Element> elements = type.getEnclosedElements();
final List<Element> list = new ArrayList<>(elements);
final TypeMirror superclass = type.getSuperclass();
if ( superclass.getKind() == TypeKind.DECLARED ) {
final DeclaredType declaredType = (DeclaredType) superclass;
final TypeElement typeElement = (TypeElement) declaredType.asElement();
for ( Element inherited : getAllMembers(typeElement) ) {
if ( notOverridden(type, inherited, elements) ) {
list.add( inherited );
}
}
}
for (TypeMirror supertype : type.getInterfaces()) {
final DeclaredType declaredType = (DeclaredType) supertype;
final TypeElement typeElement = (TypeElement) declaredType.asElement();
for ( Element inherited : getAllMembers(typeElement) ) {
if ( notOverridden(type, inherited, elements) ) {
list.add( inherited );
}
}
}
return list;
}
private boolean notOverridden(TypeElement type, Element inherited, List<? extends Element> elements) {
return !(inherited instanceof ExecutableElement)
|| elements.stream().noneMatch(member -> member instanceof ExecutableElement
&& getElementUtils().overrides((ExecutableElement) member, (ExecutableElement) inherited, type));
}
} }

View File

@ -381,7 +381,7 @@ public class AnnotationMetaEntity extends AnnotationMeta {
if ( repository ) { if ( repository ) {
final List<ExecutableElement> methodsOfClass = final List<ExecutableElement> methodsOfClass =
methodsIn( context.getElementUtils().getAllMembers(element) ); methodsIn( context.getAllMembers(element) );
for ( ExecutableElement method: methodsOfClass ) { for ( ExecutableElement method: methodsOfClass ) {
if ( containsAnnotation( method, HQL, SQL, JD_QUERY, FIND, JD_FIND ) ) { if ( containsAnnotation( method, HQL, SQL, JD_QUERY, FIND, JD_FIND ) ) {
queryMethods.add( method ); queryMethods.add( method );
@ -1004,7 +1004,7 @@ public class AnnotationMetaEntity extends AnnotationMeta {
} }
final AnnotationValue annotationVal = final AnnotationValue annotationVal =
castNonNull(getAnnotationValue(annotation, "mappedBy")); castNonNull(getAnnotationValue(annotation, "mappedBy"));
for ( Element member : context.getElementUtils().getAllMembers(assocTypeElement) ) { for ( Element member : context.getAllMembers(assocTypeElement) ) {
if ( propertyName(this, member).contentEquals(mappedBy) ) { if ( propertyName(this, member).contentEquals(mappedBy) ) {
validateBackRef(memberOfClass, annotation, assocTypeElement, member, annotationVal); validateBackRef(memberOfClass, annotation, assocTypeElement, member, annotationVal);
return; return;
@ -2127,7 +2127,7 @@ public class AnnotationMetaEntity extends AnnotationMeta {
private @Nullable Element memberMatchingPath(TypeElement entityType, StringTokenizer tokens) { private @Nullable Element memberMatchingPath(TypeElement entityType, StringTokenizer tokens) {
final AccessType accessType = getAccessType(entityType); final AccessType accessType = getAccessType(entityType);
final String nextToken = tokens.nextToken(); final String nextToken = tokens.nextToken();
for ( Element member : context.getElementUtils().getAllMembers(entityType) ) { for ( Element member : context.getAllMembers(entityType) ) {
if ( isIdRef(nextToken) && hasAnnotation( member, ID) ) { if ( isIdRef(nextToken) && hasAnnotation( member, ID) ) {
return member; return member;
} }

View File

@ -0,0 +1,7 @@
package org.hibernate.processor.test.mappedsuperclass.dao;
import jakarta.persistence.Entity;
@Entity
public class Child extends Parent {
}

View File

@ -0,0 +1,30 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
*/
package org.hibernate.processor.test.mappedsuperclass.dao;
import org.hibernate.processor.test.util.CompilationTest;
import org.hibernate.processor.test.util.TestUtil;
import org.hibernate.processor.test.util.WithClasses;
import org.junit.Test;
import static org.hibernate.processor.test.util.TestUtil.assertMetamodelClassGeneratedFor;
/**
* @author Gavin King
*/
public class DaoTest extends CompilationTest {
@Test
@WithClasses({ Parent.class, Child.class, Queries.class })
public void testDao() {
System.out.println( TestUtil.getMetaModelSourceAsString( Queries.class ) );
System.out.println( TestUtil.getMetaModelSourceAsString( Parent.class ) );
System.out.println( TestUtil.getMetaModelSourceAsString( Child.class ) );
assertMetamodelClassGeneratedFor( Queries.class );
assertMetamodelClassGeneratedFor( Parent.class );
assertMetamodelClassGeneratedFor( Child.class );
}
}

View File

@ -0,0 +1,18 @@
package org.hibernate.processor.test.mappedsuperclass.dao;
import jakarta.persistence.Id;
import jakarta.persistence.MappedSuperclass;
@MappedSuperclass
public abstract class Parent {
@Id
private Long id;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
}

View File

@ -0,0 +1,8 @@
package org.hibernate.processor.test.mappedsuperclass.dao;
import org.hibernate.annotations.processing.Find;
public interface Queries {
@Find
Child getChild(Long id);
}