Наследование в параметрах аннотации - PullRequest
2 голосов
/ 14 февраля 2012

Я пытаюсь наследовать следующий параметр в интерфейсе 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);
}

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

public interface EventRepository extends ItemRepository<Event> {

    public final static String type = "Event";
}

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

Спасибо

Ответы [ 3 ]

1 голос
/ 14 февраля 2012

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

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

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

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

1 голос
/ 14 февраля 2012

Я не эксперт по 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 голосов
/ 16 февраля 2012

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

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...