2012-02-13 1 views
2

Я пытаюсь унаследовать следующий параметр в интерфейсе Java (пример из Spring Data JPA, но вопрос, как правило, о параметрах в аннотации):Наследование в аннотации параметры

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); 
} 

так, что в унаследованных интерфейсов I могли бы просто:

public interface EventRepository extends ItemRepository<Event> { 

    public final static String type = "Event"; 
} 

Но, к сожалению, строковое значение переменной «типа» связан с переменной слишком поздно, поэтому при создании аннотации, то значение по-прежнему нулевой. Могу ли я заставить компилятор связать переменную с дочерним интерфейсом?

Благодаря

+0

Я считаю, что это то, на что рассчитан одиночный шаблон. –

+1

Но это интерфейсы, а не классы. Не могли бы вы рассказать? Я заинтересован! :) – m0skit0

ответ

1

Короче говоря, нет. Вы не можете заставить компилятор «связать переменную с дочерним интерфейсом».

Компилятор Java должен иметь возможность определять все значения аннотации во время компиляции. Он должен записать в файл класса для ItemRepository постоянное значение, которое будет помещено в аннотацию @Query. Какую постоянную ценность вы бы себе представляли для своего кода?

Как это бывает, компилятор может определить из вашего кода значение для этой аннотации во время компиляции. Однако это не то значение, которое вы хотите. (Я предполагаю, что вы случайно опущен static модификатор из поля type в ItemRepository - Я считаю, что ваш код не компилируется в противном случае он также не будет компилировать, если вы заменили ваш type поля с помощью метода getType().).

Ваш код похож, что во время компиляции можно определить значения аннотаций для субинтерфейсов. Проблема в том, что это не определить во время компиляции значение аннотации для суперинтерфейса ItemRepository.

1

Я не эксперт Java, но я не думаю, что вы можете сделать это. Родительские классы не знают о детях. Однако вы можете сделать что-то вроде:

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) 
} 
0

В конце концов, я был так недоволен поведением и негибкостью, так что я написал себе небольшой инструмент. Пример использования здесь:

https://github.com/knyttl/Maite/wiki/Maite-Persistence

Есть двое детей классов и родительский класс, которые определяют функциональность. Но трюк находится в свободном интерфейсе построения запроса. Как вы думаете?

+0

Страница не найдена ошибка. –