HHH-17864 generate static metamodel fields for embeddables
This commit is contained in:
parent
b7038b2294
commit
f3dd73dd2f
|
@ -483,6 +483,8 @@ public class HibernateProcessor extends AbstractProcessor {
|
|||
}
|
||||
addMetamodelToContext( typeElement, metaEntity );
|
||||
if ( context.generateJakartaDataStaticMetamodel()
|
||||
// no static metamodel for embeddable classes in Jakarta Data
|
||||
&& hasAnnotation( element, ENTITY, MAPPED_SUPERCLASS )
|
||||
// Don't generate a Jakarta Data metamodel
|
||||
// if this entity was partially mapped in XML
|
||||
&& alreadyExistingMetaEntity == null ) {
|
||||
|
|
|
@ -734,25 +734,72 @@ public class AnnotationMetaEntity extends AnnotationMeta {
|
|||
|
||||
private void addPersistentMembers(List<? extends Element> membersOfClass, AccessType membersKind) {
|
||||
for ( Element memberOfClass : membersOfClass ) {
|
||||
if ( isPersistent( memberOfClass, membersKind ) ) {
|
||||
if ( jakartaDataStaticModel ) {
|
||||
final DataAnnotationMetaAttribute dataMetaAttribute =
|
||||
memberOfClass.asType()
|
||||
.accept( new DataMetaAttributeGenerationVisitor( this, context ), memberOfClass );
|
||||
if ( dataMetaAttribute != null ) {
|
||||
members.put( '_' + dataMetaAttribute.getPropertyName(), dataMetaAttribute );
|
||||
}
|
||||
}
|
||||
else {
|
||||
final AnnotationMetaAttribute jpaMetaAttribute =
|
||||
memberOfClass.asType()
|
||||
.accept( new MetaAttributeGenerationVisitor( this, context ), memberOfClass );
|
||||
if ( jpaMetaAttribute != null ) {
|
||||
members.put( jpaMetaAttribute.getPropertyName(), jpaMetaAttribute );
|
||||
if ( isPersistent(memberOfClass, membersKind) ) {
|
||||
addPersistentMember(memberOfClass);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void addPersistentMember(Element memberOfClass) {
|
||||
if ( jakartaDataStaticModel ) {
|
||||
final DataAnnotationMetaAttribute dataMetaAttribute =
|
||||
memberOfClass.asType()
|
||||
.accept( new DataMetaAttributeGenerationVisitor(this, context), memberOfClass );
|
||||
if ( dataMetaAttribute != null ) {
|
||||
final String path = dataMetaAttribute.getPropertyName();
|
||||
members.put('_' + path, dataMetaAttribute);
|
||||
if ( isEmbedded(memberOfClass) ) {
|
||||
final TypeMirror type = attributeType(memberOfClass);
|
||||
final DeclaredType declaredType = (DeclaredType) type;
|
||||
final TypeElement typeElement = (TypeElement) declaredType.asElement();
|
||||
for ( Element field : fieldsIn( typeElement.getEnclosedElements() ) ) {
|
||||
addEmbeddablePersistentMember(field, path, AccessType.FIELD);
|
||||
}
|
||||
for ( Element method : methodsIn( typeElement.getEnclosedElements() ) ) {
|
||||
if ( isGetterOrSetter(method) ) {
|
||||
addEmbeddablePersistentMember(method, path, AccessType.PROPERTY);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
final AnnotationMetaAttribute jpaMetaAttribute =
|
||||
memberOfClass.asType()
|
||||
.accept( new MetaAttributeGenerationVisitor( this, context ), memberOfClass);
|
||||
if ( jpaMetaAttribute != null ) {
|
||||
members.put( jpaMetaAttribute.getPropertyName(), jpaMetaAttribute );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void addEmbeddablePersistentMember(Element memberOfEmbeddable, String path, AccessType membersKind) {
|
||||
if ( isPersistent(memberOfEmbeddable, membersKind) ) { //TODO respect AccessType of embeddable
|
||||
final DataAnnotationMetaAttribute metaAttribute =
|
||||
memberOfEmbeddable.asType()
|
||||
.accept( new DataMetaAttributeGenerationVisitor(this, path, context),
|
||||
memberOfEmbeddable );
|
||||
if (metaAttribute != null) {
|
||||
members.put('_' + metaAttribute.getPropertyName(),
|
||||
metaAttribute);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static boolean isEmbedded(Element memberOfClass) {
|
||||
if ( hasAnnotation(memberOfClass, EMBEDDED) ) {
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
final TypeMirror type = attributeType(memberOfClass);
|
||||
if ( type.getKind() == TypeKind.DECLARED ) {
|
||||
final DeclaredType declaredType = (DeclaredType) type;
|
||||
return hasAnnotation( declaredType.asElement(), EMBEDDABLE );
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void validateAssociation(Element memberOfClass) {
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
*/
|
||||
package org.hibernate.processor.annotation;
|
||||
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
import org.hibernate.processor.model.MetaAttribute;
|
||||
import org.hibernate.processor.model.Metamodel;
|
||||
|
||||
|
@ -21,14 +22,17 @@ import static org.hibernate.processor.util.TypeUtils.propertyName;
|
|||
*/
|
||||
public class DataAnnotationMetaAttribute implements MetaAttribute {
|
||||
|
||||
final Element element;
|
||||
final AnnotationMetaEntity parent;
|
||||
private final Element element;
|
||||
private final AnnotationMetaEntity parent;
|
||||
private final String type;
|
||||
private final @Nullable String path;
|
||||
|
||||
public DataAnnotationMetaAttribute(AnnotationMetaEntity parent, Element element, String type) {
|
||||
public DataAnnotationMetaAttribute(
|
||||
AnnotationMetaEntity parent, Element element, String type, @Nullable String path) {
|
||||
this.element = element;
|
||||
this.parent = parent;
|
||||
this.type = type;
|
||||
this.path = path;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -48,7 +52,8 @@ public class DataAnnotationMetaAttribute implements MetaAttribute {
|
|||
@Override
|
||||
public String getAttributeDeclarationString() {
|
||||
final String className = parent.importType( parent.getQualifiedName() );
|
||||
final String memberName = element.getSimpleName().toString();
|
||||
final String elementName = element.getSimpleName().toString();
|
||||
final String memberName = path == null ? elementName : path + '.' + elementName;
|
||||
final String impl = isTextual()
|
||||
? parent.importType("jakarta.data.metamodel.impl.TextAttributeRecord")
|
||||
: parent.importType("jakarta.data.metamodel.impl.SortableAttributeRecord");
|
||||
|
@ -63,22 +68,24 @@ public class DataAnnotationMetaAttribute implements MetaAttribute {
|
|||
.append( "<" )
|
||||
.append( className )
|
||||
.append( "> " )
|
||||
.append( getPropertyName() )
|
||||
.append( getPropertyName().replace('.','_') )
|
||||
.append(" = new ")
|
||||
.append( impl )
|
||||
.append( "<>(\"" )
|
||||
.append(memberName)
|
||||
.append( getPropertyName() )
|
||||
.append( "\");" )
|
||||
.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getAttributeNameDeclarationString(){
|
||||
final String fieldName =
|
||||
getUpperUnderscoreCaseFromLowerCamelCase(getPropertyName().replace('.', '_'));
|
||||
return new StringBuilder()
|
||||
.append("public static final ")
|
||||
.append(parent.importType(String.class.getName()))
|
||||
.append(" ")
|
||||
.append(getUpperUnderscoreCaseFromLowerCamelCase(getPropertyName()))
|
||||
.append(fieldName)
|
||||
.append(" = ")
|
||||
.append("\"")
|
||||
.append(getPropertyName())
|
||||
|
@ -89,7 +96,8 @@ public class DataAnnotationMetaAttribute implements MetaAttribute {
|
|||
|
||||
@Override
|
||||
public String getPropertyName() {
|
||||
return propertyName( parent, element );
|
||||
final String propertyName = propertyName(parent, element);
|
||||
return path == null ? propertyName : path + '.' + propertyName;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -33,10 +33,18 @@ public class DataMetaAttributeGenerationVisitor extends SimpleTypeVisitor8<@Null
|
|||
|
||||
private final AnnotationMetaEntity entity;
|
||||
private final Context context;
|
||||
private final @Nullable String path;
|
||||
|
||||
DataMetaAttributeGenerationVisitor(AnnotationMetaEntity entity, Context context) {
|
||||
this.entity = entity;
|
||||
this.context = context;
|
||||
this.path = null;
|
||||
}
|
||||
|
||||
DataMetaAttributeGenerationVisitor(AnnotationMetaEntity entity, String path, Context context) {
|
||||
this.entity = entity;
|
||||
this.context = context;
|
||||
this.path = path;
|
||||
}
|
||||
|
||||
private Types typeUtils() {
|
||||
|
@ -45,19 +53,19 @@ public class DataMetaAttributeGenerationVisitor extends SimpleTypeVisitor8<@Null
|
|||
|
||||
@Override
|
||||
public @Nullable DataAnnotationMetaAttribute visitPrimitive(PrimitiveType primitiveType, Element element) {
|
||||
return new DataAnnotationMetaAttribute( entity, element, toTypeString( primitiveType ) );
|
||||
return new DataAnnotationMetaAttribute( entity, element, toTypeString( primitiveType ), path );
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable DataAnnotationMetaAttribute visitArray(ArrayType arrayType, Element element) {
|
||||
return new DataAnnotationMetaAttribute( entity, element, toArrayTypeString( arrayType, context ) );
|
||||
return new DataAnnotationMetaAttribute( entity, element, toArrayTypeString( arrayType, context ), path );
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable DataAnnotationMetaAttribute visitTypeVariable(TypeVariable typeVariable, Element element) {
|
||||
// METAGEN-29 - for a type variable we use the upper bound
|
||||
return new DataAnnotationMetaAttribute( entity, element,
|
||||
typeUtils().erasure( typeVariable.getUpperBound() ).toString() );
|
||||
typeUtils().erasure( typeVariable.getUpperBound() ).toString(), path );
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -72,7 +80,7 @@ public class DataMetaAttributeGenerationVisitor extends SimpleTypeVisitor8<@Null
|
|||
}
|
||||
else if ( isBasicAttribute( element, returnedElement, context ) ) {
|
||||
final String type = targetEntity != null ? targetEntity : returnedElement.getQualifiedName().toString();
|
||||
return new DataAnnotationMetaAttribute( entity, element, type );
|
||||
return new DataAnnotationMetaAttribute( entity, element, type, path );
|
||||
}
|
||||
else {
|
||||
return null;
|
||||
|
|
|
@ -22,6 +22,7 @@ public final class Constants {
|
|||
public static final String ENTITY = "jakarta.persistence.Entity";
|
||||
public static final String MAPPED_SUPERCLASS = "jakarta.persistence.MappedSuperclass";
|
||||
public static final String EMBEDDABLE = "jakarta.persistence.Embeddable";
|
||||
public static final String EMBEDDED = "jakarta.persistence.Embedded";
|
||||
public static final String ID = "jakarta.persistence.Id";
|
||||
public static final String ID_CLASS = "jakarta.persistence.IdClass";
|
||||
public static final String EMBEDDED_ID = "jakarta.persistence.EmbeddedId";
|
||||
|
|
|
@ -43,6 +43,7 @@ import static org.hibernate.processor.util.Constants.ACCESS;
|
|||
import static org.hibernate.processor.util.Constants.BASIC;
|
||||
import static org.hibernate.processor.util.Constants.ELEMENT_COLLECTION;
|
||||
import static org.hibernate.processor.util.Constants.EMBEDDABLE;
|
||||
import static org.hibernate.processor.util.Constants.EMBEDDED;
|
||||
import static org.hibernate.processor.util.Constants.EMBEDDED_ID;
|
||||
import static org.hibernate.processor.util.Constants.ENTITY;
|
||||
import static org.hibernate.processor.util.Constants.ID;
|
||||
|
@ -551,7 +552,7 @@ public final class TypeUtils {
|
|||
}
|
||||
|
||||
public static boolean isBasicAttribute(Element element, Element returnedElement, Context context) {
|
||||
return hasAnnotation( element, BASIC, ONE_TO_ONE, MANY_TO_ONE, EMBEDDED_ID, ID )
|
||||
return hasAnnotation( element, BASIC, ONE_TO_ONE, MANY_TO_ONE, EMBEDDED, EMBEDDED_ID, ID )
|
||||
|| hasAnnotation( element, "org.hibernate.annotations.Type") // METAGEN-28
|
||||
|| returnedElement.asType().accept( new BasicAttributeVisitor( context ), returnedElement );
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue