@@ -470,6 +470,10 @@ && containsAnnotation( method, HQL, SQL, FIND ) ) {
470
470
addPersistentMembers ( gettersAndSettersOfClass , AccessType .PROPERTY );
471
471
472
472
addIdClassIfNeeded ( fieldsOfClass , gettersAndSettersOfClass );
473
+
474
+ if ( hasAnnotation ( element , ENTITY ) && isPanache2Type (element ) && !jakartaDataStaticModel ) {
475
+ addRepositoryMembers ( element );
476
+ }
473
477
}
474
478
475
479
addAuxiliaryMembers ();
@@ -523,6 +527,41 @@ private void addIdClassIfNeeded(List<VariableElement> fields, List<ExecutableEle
523
527
}
524
528
}
525
529
530
+ private void addRepositoryMembers (TypeElement element ) {
531
+ Element managedBlockingRepository = null ;
532
+ Element statelessBlockingRepository = null ;
533
+ Element managedReactiveRepository = null ;
534
+ Element statelessReactiveRepository = null ;
535
+ for ( Element enclosedElement : element .getEnclosedElements () ) {
536
+ if ( enclosedElement .getKind () == ElementKind .INTERFACE ) {
537
+ members .put ( enclosedElement .getSimpleName ().toString (), new CDIAccessorMetaAttribute ( this , enclosedElement ) );
538
+ if ( implementsInterface ( (TypeElement ) enclosedElement , Constants .PANACHE2_MANAGED_BLOCKING_REPOSITORY_BASE ) ) {
539
+ managedBlockingRepository = enclosedElement ;
540
+ }
541
+ else if ( implementsInterface ( (TypeElement ) enclosedElement , Constants .PANACHE2_STATELESS_BLOCKING_REPOSITORY_BASE ) ) {
542
+ statelessBlockingRepository = enclosedElement ;
543
+ }
544
+ else if ( implementsInterface ( (TypeElement ) enclosedElement , Constants .PANACHE2_MANAGED_REACTIVE_REPOSITORY_BASE ) ) {
545
+ managedReactiveRepository = enclosedElement ;
546
+ }
547
+ else if ( implementsInterface ( (TypeElement ) enclosedElement , Constants .PANACHE2_STATELESS_REACTIVE_REPOSITORY_BASE ) ) {
548
+ statelessReactiveRepository = enclosedElement ;
549
+ }
550
+ }
551
+ }
552
+ if ( quarkusInjection ) {
553
+ // FIXME: perhaps import id type?
554
+ TypeMirror idType = findIdType ();
555
+ addAccessors (managedBlockingRepository , idType , "managedBlocking" , PANACHE2_MANAGED_BLOCKING_REPOSITORY_BASE );
556
+ addAccessors (statelessBlockingRepository , idType , "statelessBlocking" , PANACHE2_STATELESS_BLOCKING_REPOSITORY_BASE );
557
+ // Only add those if HR is in the classpath, otherwise it causes a compilation issue
558
+ if ( context .usesQuarkusReactiveCommon () ) {
559
+ addAccessors (managedReactiveRepository , idType , "managedReactive" , PANACHE2_MANAGED_REACTIVE_REPOSITORY_BASE );
560
+ addAccessors (statelessReactiveRepository , idType , "statelessReactive" , PANACHE2_STATELESS_REACTIVE_REPOSITORY_BASE );
561
+ }
562
+ }
563
+ }
564
+
526
565
private List <MetaAttribute > getIdMemberNames (List <VariableElement > fields , List <ExecutableElement > methods ) {
527
566
final List <MetaAttribute > components = new ArrayList <>();
528
567
for ( var field : fields ) {
@@ -650,6 +689,56 @@ private boolean isEquivalentPrimitiveType(TypeMirror type, TypeMirror match) {
650
689
&& isSameType ( context .getTypeUtils ().boxedClass ( ((PrimitiveType ) type ) ).asType (), match );
651
690
}
652
691
692
+ private void addAccessors (@ Nullable Element repositoryType , @ Nullable TypeMirror idType ,
693
+ String repositoryAccessor , String repositorySuperType ) {
694
+ TypeElement finalPrimaryEntity = primaryEntity ;
695
+ if ( repositoryType != null ) {
696
+ members .put ( repositoryAccessor , new CDIAccessorMetaAttribute ( this , repositoryAccessor , repositoryType .getSimpleName ().toString () ) );
697
+ }
698
+ else if ( idType != null && finalPrimaryEntity != null ) {
699
+ String repositoryTypeName = "Panache" +repositoryAccessor .substring (0 ,1 ).toUpperCase ()+repositoryAccessor .substring (1 )+"Repository" ;
700
+ members .put ( repositoryAccessor , new CDIAccessorMetaAttribute ( this , repositoryAccessor , repositoryTypeName ) );
701
+ members .put ( repositoryAccessor + "Repository" , new CDITypeMetaAttribute ( this , repositoryTypeName , repositorySuperType +"<" + finalPrimaryEntity .getSimpleName ()+", " + idType .toString ()+">" ) );
702
+ }
703
+ }
704
+
705
+ private @ Nullable TypeMirror findIdType () {
706
+ Element idMember = findIdMember ();
707
+ TypeElement primaryEntityForTest = primaryEntity ;
708
+ if ( idMember != null && primaryEntityForTest != null ) {
709
+ TypeMirror typedIdMember = this .context .getTypeUtils ().asMemberOf ((DeclaredType ) primaryEntityForTest .asType (), idMember );
710
+ return switch (typedIdMember .getKind ()) {
711
+ case ARRAY , DECLARED , BOOLEAN , BYTE , CHAR , SHORT , INT , LONG , FLOAT , DOUBLE -> typedIdMember ;
712
+ case EXECUTABLE -> ((ExecutableType ) typedIdMember ).getReturnType ();
713
+ default -> {
714
+ message ( element ,
715
+ "Unhandled id member kind: " +typedIdMember +" for id " +idMember ,
716
+ Diagnostic .Kind .ERROR );
717
+ yield null ;
718
+ }
719
+ };
720
+ }
721
+ return null ;
722
+ }
723
+
724
+ private @ Nullable Element findIdMember () {
725
+ if ( primaryEntity == null ) {
726
+ message ( element ,
727
+ "No primary entity defined to find id member" ,
728
+ Diagnostic .Kind .ERROR );
729
+ return null ;
730
+ }
731
+ for ( Element member : context .getAllMembers ( primaryEntity ) ) {
732
+ if ( hasAnnotation ( member , ID , EMBEDDED_ID ) ) {
733
+ return member ;
734
+ }
735
+ }
736
+ message ( element ,
737
+ "Could not find any member annotated with @Id or @EmbeddedId" ,
738
+ Diagnostic .Kind .ERROR );
739
+ return null ;
740
+ }
741
+
653
742
private boolean checkEntities (List <ExecutableElement > lifecycleMethods , boolean hibernateRepo ) {
654
743
boolean foundPersistenceEntity = false ;
655
744
VariableElement nonPersistenceParameter = null ;
0 commit comments