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