1

I want to create a meta-annotation, called @QueryRequest, for Spring's @RequestBody like shown in below.

@Target(ElementType.PARAMETER)
@Retention(RetentionPolicy.RUNTIME)
@RequestBody
public @interface QueryRequest {
}

However, it throws a compilation error called, java: annotation type not applicable to this kind of declaration

When I searched in the internet, it tells me to verify the correct @Target type. Anyway, as you can already see my @Target and @Retention values, they are as same as what Spring's @RequestBody is, but still above error is thrown.

I have successfully created meta-annotations for @Target=ElementType.METHOD or ElementType.TYPE types, but I could not make work above annotation.

Anybody know what is actually wrong with above meta-annotation?

isuru89
  • 742
  • 11
  • 19
  • I am guessing it is because @RequestBody can't be used on other interfaces and hence on other annotations. Not sure what is the workaround – J Asgarov Aug 15 '20 at 14:25
  • 3
    Related question: https://stackoverflow.com/a/40861154/2148365 – Michiel Aug 15 '20 at 15:00
  • 1
    `@RequestBody` contains the following `@Target({ElementType.PARAMETER})`, so you can use it only in a parameter. If you take a look to `@Documented` one, for example, you will see `@Target(ElementType.ANNOTATION_TYPE)`, that is the reason why is possible to use it in `@RequestBody` – doctore Aug 15 '20 at 15:11

2 Answers2

2

Since @RequestBody is annotated @Target(ElementType.PARAMETER)you can only add this annotation on a parameter. Here you are trying to apply the annotation on an annotation. In order to achieve that @RequestBody should have been annotated with @Target(ElementType.ANNOTATION_TYPE) or with @Target(ElementType.TYPE).

For example this code will not work because you cannot annotate QueryRequest on an annotation:

@Target(ElementType.PARAMETER)
@Documented
@Retention(RetentionPolicy.RUNTIME)
public @interface QueryRequest {
}
@Target(ElementType.ANNOTATION_TYPE)
@Documented
@Retention(RetentionPolicy.RUNTIME)
@QueryRequest
@interface NextQueryRequest

However this will work, because you are allowing QueryResult to be put on an annotation

@Target(ElementType.TYPE)
@Documented
@Retention(RetentionPolicy.RUNTIME)
public @interface QueryRequest {
}
@Target(ElementType.ANNOTATION_TYPE)
@Documented
@Retention(RetentionPolicy.RUNTIME)
@QueryRequest
@interface NextQueryRequest

 @Target(ElementType.ANNOTATION_TYPE)
@Documented
@Retention(RetentionPolicy.RUNTIME)
public @interface QueryRequest {
}
@Target(ElementType.ANNOTATION_TYPE)
@Documented
@Retention(RetentionPolicy.RUNTIME)
@QueryRequest
@interface NextQueryRequest
marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
Daniel Jacob
  • 1,455
  • 9
  • 17
0

@Daniel has explained why this happens with an example.

Also, anyone who is looking for a workaround should read this answer as @Michiel mentioned above. https://stackoverflow.com/a/40861154/2148365

isuru89
  • 742
  • 11
  • 19