Reputation: 12416
I am trying to inherit following parameter in a java interface (an example from Spring Data JPA, but the question is generally about parameters to annotations):
public interface ItemRepository<T extends Item> extends BaseRepository<T> {
public final String type = null;
@Query("select distinct i from " + type + " i " +
"join i.tags t " +
"join fetch i.locale where t = ?1")
public List<T> findByTag(Tag t);
}
so that in inherited interfaces I could have just:
public interface EventRepository extends ItemRepository<Event> {
public final static String type = "Event";
}
But unfortunately the string value of variable "type" is associated to the variable too late, so when the annotation is created, the value is still null. Can I force the compiler to associate the variable from the child interface?
Thanks
Upvotes: 2
Views: 1937
Reputation: 12416
In the end, I was so unhappy about the behaviour and inflexibility, so that I wrote myself a small tool. An example of using is here:
https://github.com/knyttl/Maite/wiki/Maite-Persistence
There are two children classes and the parent class which define the functionality. But the trick is in a fluent interface of building the query. What do you think?
Upvotes: 0
Reputation: 25863
I'm no Java expert, but I don't think you can do so. Parent classes have no knowledge about children. However you can do something like:
public interface ItemRepository<T extends Item> extends BaseRepository<T> {
public final String type = null;
public static final String QUERY_PART1 = "select distinct i from ";
public static final String QUERY_PART2 = " i " +
"join i.tags t " +
"join fetch i.locale where t = ?1";
public List<T> findByTag(Tag t);
}
public interface EventRepository extends ItemRepository<Event> {
public final static String type = "Event";
@Query(QUERY_PART1 + type + QUERY_PART2)
}
Upvotes: 1
Reputation: 64949
In short, no. You can't force the compiler to 'associate the variable from the child interface'.
The Java compiler needs to be able to determine all annotation values at compile time. It needs to write out into the class file for ItemRepository
a constant value to put in the @Query
annotation. What constant value would you imagine this would be for your code?
As it happens, the compiler can determine from your code a value for this annotation at compile time. However, it's not exactly the value you want. (I am assuming that you've accidentally omitted the static
modifier from the field type
in ItemRepository
- I believe your code wouldn't compile otherwise. It also wouldn't compile if you replaced your type
field with a getType()
method.)
Your code looks like it can determine at compile time the annotation values for the subinterfaces. The problem is that it's not possible to determine at compile time the annotation value for the superinterface ItemRepository
.
Upvotes: 1