77import org .checkerframework .checker .nullness .qual .Nullable ;
88import org .hibernate .processor .annotation .AnnotationMetaEntity ;
99import org .hibernate .processor .annotation .AnnotationMetaPackage ;
10+ import org .hibernate .processor .annotation .NonManagedMetamodel ;
1011import org .hibernate .processor .model .Metamodel ;
1112import org .hibernate .processor .util .Constants ;
1213import org .hibernate .processor .xml .JpaDescriptorParser ;
@@ -359,11 +360,11 @@ private void processClasses(RoundEnvironment roundEnvironment) {
359360 }
360361
361362 for ( Element element : roundEnvironment .getRootElements () ) {
362- processElement ( element );
363+ processElement ( element , null );
363364 }
364365 }
365366
366- private void processElement (Element element ) {
367+ private void processElement (Element element , @ Nullable Element parent ) {
367368 try {
368369 if ( !included ( element )
369370 || hasAnnotation ( element , Constants .EXCLUDE )
@@ -373,7 +374,7 @@ private void processElement(Element element) {
373374 }
374375 else if ( isEntityOrEmbeddable ( element ) && !element .getModifiers ().contains ( Modifier .PRIVATE )) {
375376 context .logMessage ( Diagnostic .Kind .OTHER , "Processing annotated entity class '" + element + "'" );
376- handleRootElementAnnotationMirrors ( element );
377+ handleRootElementAnnotationMirrors ( element , parent );
377378 }
378379 else if ( hasAuxiliaryAnnotations ( element ) ) {
379380 context .logMessage ( Diagnostic .Kind .OTHER , "Processing annotated class '" + element + "'" );
@@ -405,12 +406,29 @@ else if ( element instanceof TypeElement typeElement ) {
405406 break ;
406407 }
407408 }
409+ if ( enclosesEntityOrEmbeddable ( element ) ) {
410+ AnnotationMetaEntity parentMeta = null ;
411+ if ( parent instanceof TypeElement parentElement ) {
412+ final String key = parentElement .getQualifiedName ().toString ();
413+ if ( context .getMetamodel ( key ) instanceof AnnotationMetaEntity parentMetaEntity ) {
414+ parentMeta = parentMetaEntity ;
415+ }
416+ }
417+ if (element .getSimpleName ().toString ().equals ( "OffsetDateTimeTest" )) {
418+ System .err .println ("Create OffsetDateTimeTest as non-entity class#1" );
419+ }
420+ final NonManagedMetamodel metaEntity =
421+ NonManagedMetamodel .create (
422+ typeElement , context ,
423+ parentMeta );
424+ context .addMetaEntity ( metaEntity .getQualifiedName (), metaEntity );
425+ }
408426 }
409427 }
410428 if ( isClassOrRecordType ( element ) ) {
411429 for ( final Element child : element .getEnclosedElements () ) {
412430 if ( isClassOrRecordType ( child ) ) {
413- processElement ( child );
431+ processElement ( child , element );
414432 }
415433 }
416434 }
@@ -443,7 +461,16 @@ private void createMetaModelClasses() {
443461 }
444462
445463 for ( Metamodel entity : context .getMetaEntities () ) {
446- if ( !context .isAlreadyGenerated (entity ) ) {
464+ if ( !context .isAlreadyGenerated (entity ) && !entity .hasParent ()) {
465+ context .logMessage ( Diagnostic .Kind .OTHER ,
466+ "Writing Jakarta Persistence metamodel for entity '" + entity + "'" );
467+ ClassWriter .writeFile ( entity , context );
468+ context .markGenerated (entity );
469+ }
470+ }
471+
472+ for ( Metamodel entity : context .getMetaEntities () ) {
473+ if ( !context .isAlreadyGenerated (entity ) && !entity .hasParent ()) {
447474 context .logMessage ( Diagnostic .Kind .OTHER ,
448475 "Writing Jakarta Persistence metamodel for entity '" + entity + "'" );
449476 ClassWriter .writeFile ( entity , context );
@@ -475,7 +502,7 @@ private void processEmbeddables(Collection<Metamodel> models) {
475502 final int toProcessCountBeforeLoop = models .size ();
476503 for ( Metamodel metamodel : models ) {
477504 // see METAGEN-36
478- if ( context .isAlreadyGenerated (metamodel ) ) {
505+ if ( context .isAlreadyGenerated (metamodel ) || metamodel . hasParent () ) {
479506 processed .add ( metamodel );
480507 }
481508 else if ( !modelGenerationNeedsToBeDeferred (models , metamodel ) ) {
@@ -529,6 +556,18 @@ private boolean modelGenerationNeedsToBeDeferred(Collection<Metamodel> entities,
529556 return false ;
530557 }
531558
559+ private static boolean enclosesEntityOrEmbeddable (Element element ) {
560+ if ( !(element instanceof TypeElement typeElement ) ) {
561+ return false ;
562+ }
563+ for ( final Element enclosedElement : typeElement .getEnclosedElements () ) {
564+ if ( isEntityOrEmbeddable ( enclosedElement ) || enclosesEntityOrEmbeddable ( enclosedElement ) ) {
565+ return true ;
566+ }
567+ }
568+ return false ;
569+ }
570+
532571 private static boolean isEntityOrEmbeddable (Element element ) {
533572 return hasAnnotation (
534573 element ,
@@ -560,7 +599,7 @@ private boolean hasAuxiliaryAnnotations(Element element) {
560599 );
561600 }
562601
563- private void handleRootElementAnnotationMirrors (final Element element ) {
602+ private void handleRootElementAnnotationMirrors (final Element element , @ Nullable Element parent ) {
564603 if ( isClassOrRecordType ( element ) ) {
565604 if ( isEntityOrEmbeddable ( element ) ) {
566605 final TypeElement typeElement = (TypeElement ) element ;
@@ -577,12 +616,23 @@ private void handleRootElementAnnotationMirrors(final Element element) {
577616 + "' since XML configuration is metadata complete." );
578617 }
579618 else {
619+ AnnotationMetaEntity parentMetaEntity = null ;
620+ if ( parent instanceof TypeElement parentTypeElement ) {
621+ if ( context .getMetamodel (
622+ parentTypeElement .getQualifiedName ().toString () )
623+ instanceof AnnotationMetaEntity pme ) {
624+ parentMetaEntity = pme ;
625+ }
626+ }
580627 final boolean requiresLazyMemberInitialization
581628 = hasAnnotation ( element , EMBEDDABLE , MAPPED_SUPERCLASS );
629+ if (element .getSimpleName ().toString ().equals ( "OffsetDateTimeTest" )) {
630+ System .err .println ("Create OffsetDateTimeTest in handleRootElementAnnotationMirrors#2" );
631+ }
582632 final AnnotationMetaEntity metaEntity =
583633 AnnotationMetaEntity .create ( typeElement , context ,
584634 requiresLazyMemberInitialization ,
585- true , false );
635+ true , false , parentMetaEntity );
586636 if ( alreadyExistingMetaEntity != null ) {
587637 metaEntity .mergeInMembers ( alreadyExistingMetaEntity );
588638 }
@@ -596,10 +646,13 @@ && hasAnnotation( element, ENTITY, MAPPED_SUPERCLASS )
596646 // let a handwritten metamodel "override" the generated one
597647 // (this is used in the Jakarta Data TCK)
598648 && !hasHandwrittenMetamodel (element ) ) {
649+ if (element .getSimpleName ().toString ().equals ( "OffsetDateTimeTest" )) {
650+ System .err .println ("Create OffsetDateTimeTest in handleRootElementAnnotationMirrors#3" );
651+ }
599652 final AnnotationMetaEntity dataMetaEntity =
600653 AnnotationMetaEntity .create ( typeElement , context ,
601654 requiresLazyMemberInitialization ,
602- true , true );
655+ true , true , parentMetaEntity );
603656// final Metamodel alreadyExistingDataMetaEntity =
604657// tryGettingExistingDataEntityFromContext( mirror, '_' + qualifiedName );
605658// if ( alreadyExistingDataMetaEntity != null ) {
0 commit comments