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 ;
@@ -361,11 +362,11 @@ private void processClasses(RoundEnvironment roundEnvironment) {
361362 }
362363
363364 for ( Element element : roundEnvironment .getRootElements () ) {
364- processElement ( element );
365+ processElement ( element , null );
365366 }
366367 }
367368
368- private void processElement (Element element ) {
369+ private void processElement (Element element , @ Nullable Element parent ) {
369370 try {
370371 if ( !included ( element )
371372 || hasAnnotation ( element , Constants .EXCLUDE )
@@ -375,7 +376,7 @@ private void processElement(Element element) {
375376 }
376377 else if ( isEntityOrEmbeddable ( element ) && !element .getModifiers ().contains ( Modifier .PRIVATE )) {
377378 context .logMessage ( Diagnostic .Kind .OTHER , "Processing annotated entity class '" + element + "'" );
378- handleRootElementAnnotationMirrors ( element );
379+ handleRootElementAnnotationMirrors ( element , parent );
379380 }
380381 else if ( hasAuxiliaryAnnotations ( element ) ) {
381382 context .logMessage ( Diagnostic .Kind .OTHER , "Processing annotated class '" + element + "'" );
@@ -407,12 +408,29 @@ else if ( element instanceof TypeElement typeElement ) {
407408 break ;
408409 }
409410 }
411+ if ( enclosesEntityOrEmbeddable ( element ) ) {
412+ AnnotationMetaEntity parentMeta = null ;
413+ if ( parent instanceof TypeElement parentElement ) {
414+ final String key = parentElement .getQualifiedName ().toString ();
415+ if ( context .getMetamodel ( key ) instanceof AnnotationMetaEntity parentMetaEntity ) {
416+ parentMeta = parentMetaEntity ;
417+ }
418+ }
419+ if (element .getSimpleName ().toString ().equals ( "OffsetDateTimeTest" )) {
420+ System .err .println ("Create OffsetDateTimeTest as non-entity class#1" );
421+ }
422+ final NonManagedMetamodel metaEntity =
423+ NonManagedMetamodel .create (
424+ typeElement , context ,
425+ parentMeta );
426+ context .addMetaEntity ( metaEntity .getQualifiedName (), metaEntity );
427+ }
410428 }
411429 }
412430 if ( isClassOrRecordType ( element ) ) {
413431 for ( final Element child : element .getEnclosedElements () ) {
414432 if ( isClassOrRecordType ( child ) ) {
415- processElement ( child );
433+ processElement ( child , element );
416434 }
417435 }
418436 }
@@ -445,7 +463,16 @@ private void createMetaModelClasses() {
445463 }
446464
447465 for ( Metamodel entity : context .getMetaEntities () ) {
448- if ( !context .isAlreadyGenerated (entity ) ) {
466+ if ( !context .isAlreadyGenerated (entity ) && !entity .hasParent ()) {
467+ context .logMessage ( Diagnostic .Kind .OTHER ,
468+ "Writing Jakarta Persistence metamodel for entity '" + entity + "'" );
469+ ClassWriter .writeFile ( entity , context );
470+ context .markGenerated (entity );
471+ }
472+ }
473+
474+ for ( Metamodel entity : context .getMetaEntities () ) {
475+ if ( !context .isAlreadyGenerated (entity ) && !entity .hasParent ()) {
449476 context .logMessage ( Diagnostic .Kind .OTHER ,
450477 "Writing Jakarta Persistence metamodel for entity '" + entity + "'" );
451478 ClassWriter .writeFile ( entity , context );
@@ -477,7 +504,7 @@ private void processEmbeddables(Collection<Metamodel> models) {
477504 final int toProcessCountBeforeLoop = models .size ();
478505 for ( Metamodel metamodel : models ) {
479506 // see METAGEN-36
480- if ( context .isAlreadyGenerated (metamodel ) ) {
507+ if ( context .isAlreadyGenerated (metamodel ) || metamodel . hasParent () ) {
481508 processed .add ( metamodel );
482509 }
483510 else if ( !modelGenerationNeedsToBeDeferred (models , metamodel ) ) {
@@ -531,6 +558,18 @@ private boolean modelGenerationNeedsToBeDeferred(Collection<Metamodel> entities,
531558 return false ;
532559 }
533560
561+ private static boolean enclosesEntityOrEmbeddable (Element element ) {
562+ if ( !(element instanceof TypeElement typeElement ) ) {
563+ return false ;
564+ }
565+ for ( final Element enclosedElement : typeElement .getEnclosedElements () ) {
566+ if ( isEntityOrEmbeddable ( enclosedElement ) || enclosesEntityOrEmbeddable ( enclosedElement ) ) {
567+ return true ;
568+ }
569+ }
570+ return false ;
571+ }
572+
534573 private static boolean isEntityOrEmbeddable (Element element ) {
535574 return hasAnnotation (
536575 element ,
@@ -562,7 +601,7 @@ private boolean hasAuxiliaryAnnotations(Element element) {
562601 );
563602 }
564603
565- private void handleRootElementAnnotationMirrors (final Element element ) {
604+ private void handleRootElementAnnotationMirrors (final Element element , @ Nullable Element parent ) {
566605 if ( isClassOrRecordType ( element ) ) {
567606 if ( isEntityOrEmbeddable ( element ) ) {
568607 final TypeElement typeElement = (TypeElement ) element ;
@@ -579,12 +618,23 @@ private void handleRootElementAnnotationMirrors(final Element element) {
579618 + "' since XML configuration is metadata complete." );
580619 }
581620 else {
621+ AnnotationMetaEntity parentMetaEntity = null ;
622+ if ( parent instanceof TypeElement parentTypeElement ) {
623+ if ( context .getMetamodel (
624+ parentTypeElement .getQualifiedName ().toString () )
625+ instanceof AnnotationMetaEntity pme ) {
626+ parentMetaEntity = pme ;
627+ }
628+ }
582629 final boolean requiresLazyMemberInitialization
583630 = hasAnnotation ( element , EMBEDDABLE , MAPPED_SUPERCLASS );
631+ if (element .getSimpleName ().toString ().equals ( "OffsetDateTimeTest" )) {
632+ System .err .println ("Create OffsetDateTimeTest in handleRootElementAnnotationMirrors#2" );
633+ }
584634 final AnnotationMetaEntity metaEntity =
585635 AnnotationMetaEntity .create ( typeElement , context ,
586636 requiresLazyMemberInitialization ,
587- true , false );
637+ true , false , parentMetaEntity );
588638 if ( alreadyExistingMetaEntity != null ) {
589639 metaEntity .mergeInMembers ( alreadyExistingMetaEntity );
590640 }
@@ -598,10 +648,13 @@ && hasAnnotation( element, ENTITY, MAPPED_SUPERCLASS )
598648 // let a handwritten metamodel "override" the generated one
599649 // (this is used in the Jakarta Data TCK)
600650 && !hasHandwrittenMetamodel (element ) ) {
651+ if (element .getSimpleName ().toString ().equals ( "OffsetDateTimeTest" )) {
652+ System .err .println ("Create OffsetDateTimeTest in handleRootElementAnnotationMirrors#3" );
653+ }
601654 final AnnotationMetaEntity dataMetaEntity =
602655 AnnotationMetaEntity .create ( typeElement , context ,
603656 requiresLazyMemberInitialization ,
604- true , true );
657+ true , true , parentMetaEntity );
605658// final Metamodel alreadyExistingDataMetaEntity =
606659// tryGettingExistingDataEntityFromContext( mirror, '_' + qualifiedName );
607660// if ( alreadyExistingDataMetaEntity != null ) {
0 commit comments