Skip to content

AnnotatedElementUtils.getMergedRepeatableAnnotations does not return meta annotations on repeatedly-annotated class #26188

Closed as not planned
@mischkes

Description

@mischkes
  • We use a meta-annotation @As400Sql for the annotation @SQL. It is repeatable.
  • We annotate DoubleAnnotatedClass.class with two such annotations.
  • AnnotatedElementUtils.getMergedRepeatableAnnotations() does then not retreive the @SQL annotations.
  • When using an intermediate annotation (@TwoSql) it works as expected.

Observed in spring-core 5.2.8.RELEASE via spring-boot 2.3.3.RELEASE

public class As400SqlTest {

  @Target({ElementType.TYPE, ElementType.METHOD})
  @Retention(RetentionPolicy.RUNTIME)
  @Repeatable(As400SqlGroup.class)
  @Sql(config = @SqlConfig(dataSource = "as400DataSource", transactionManager =
      "as400TransactionManager"))
  public @interface As400Sql {

    @AliasFor(attribute = "scripts", annotation = Sql.class)
    String[] value() default {};
  }

  @Target({ElementType.TYPE, ElementType.METHOD})
  @Retention(RetentionPolicy.RUNTIME)
  public @interface As400SqlGroup {

    As400Sql[] value();
  }



  @As400Sql("script1")
  public static class AnnotatedClass {

  }

  @Test
  void getMergedRepeatableAnnotations_shouldReturnSql_forClassWithAs400SqlAnnotation() {
    Set<Sql> actual = AnnotatedElementUtils
        .getMergedRepeatableAnnotations(AnnotatedClass.class, Sql.class, SqlGroup.class);

    assertThat(actual).hasSize(1);
    Sql actual0 = actual.iterator().next();
    assertThat(actual0.scripts()).containsExactly("script1");
    assertThat(actual0.config().dataSource()).isEqualTo("as400DataSource");
  }


  @As400Sql("script1")
  @As400Sql("script2")
  public static class DoubleAnnotatedClass {

  }

  @Disabled("getMergedRepeatableAnnotations returns 0 annotations - why?")
  @Test
  void getMergedRepeatableAnnotations_shouldReturnTwoSql_forDoubleAnnotatedClass() {
    Set<Sql> actual = AnnotatedElementUtils
        .getMergedRepeatableAnnotations(DoubleAnnotatedClass.class, Sql.class, SqlGroup.class);

    assertThat(actual).hasSize(2);
    Iterator<Sql> actualElements = actual.iterator();
    assertThat(actualElements.next().config().dataSource()).isEqualTo("as400DataSource");
    assertThat(actualElements.next().config().dataSource()).isEqualTo("as400DataSource");
  }


  @As400Sql("script1")
  @As400Sql("script2")
  @Retention(RetentionPolicy.RUNTIME)
  public @interface TwoSql {

  }

  @TwoSql
  public static class MetaDoubleAnnotatedClass {

  }

  @Test
  void getMergedRepeatableAnnotations_shouldReturnTwoSql_forMetaDoubleAnnotatedClass() {
    Set<Sql> actual = AnnotatedElementUtils
        .getMergedRepeatableAnnotations(MetaDoubleAnnotatedClass.class, Sql.class, SqlGroup.class);

    assertThat(actual).hasSize(2);
    Iterator<Sql> actualElements = actual.iterator();
    assertThat(actualElements.next().config().dataSource()).isEqualTo("as400DataSource");
    assertThat(actualElements.next().config().dataSource()).isEqualTo("as400DataSource");
  }
}

Metadata

Metadata

Assignees

Labels

in: coreIssues in core modules (aop, beans, core, context, expression)status: duplicateA duplicate of another issue

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions