Groovy интерполировать многострочную строку в аннотации Java

Можно ли скомпилировать отличный код, где у меня есть аннотация @Sql с константой?

Приведенный ниже код представляет собой простой тест, написанный на Spock.

@Sql(statements = ["""
         INSERT INTO pracownik ($Fields.KOMPETENCJA_ID, nr_ewid) 
                                values (1, 'A');
         INSERT INTO typ_zadania (id, kod) values (1, 'KOD');
"""]
)
def "should add new qualification"() { 
  //test code omitted
}

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

Groovyc: Expected ' INSERT INTO pracownik ($Fields.KOMPETENCJA_ID, nr_ewid) values (1, 'A'); INSERT INTO typ_zadania (id, kod) values (1, 'KOD'); to be an inline constant of type java.lang.String in @org.springframework.test.context.jdbc.Sql`

Я думаю, что многострочная строка со знаком доллара оценивается для объекта GString, но поля операторов являются типом массива строк.

Могу ли я иметь отличный код с константами аннотации java в многострочной строке?

Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
2
0
668
1

Ответы 1

Проблема, с которой вы столкнулись, не имеет ничего общего с многострочным String - компилятор ожидает, что значение, переданное в атрибут statement, является встроенной константой. GString с интерполированными переменными не оправдывает этого ожидания. Вы увидите точно такую ​​же ошибку компиляции, если напишете одну строку GString, которая содержит интерполированные значения из поля класса Fields.

Похоже, вы намеревались получить имя столбца, связанное с Fields.KOMPETENCJA_ID. Замените его ожидаемым значением, поэтому интерполяция не требуется. Что-то вроде этого:

@Sql(statements = """
        INSERT INTO pracownik (kompetencja_id, nr_ewid) 
                               values (1, 'A');
        INSERT INTO typ_zadania (id, kod) values (1, 'KOD');
""")
def "should add new qualification"() {
    //test code omitted
}

One interesting fact about Groovy. The double quote " is usually used to represent GString type. However, Groovy compiler checks if the string contains any variables like ${variableName} to do the interpolation. If it finds any, it uses GString as a type, and String otherwise.

Привет, Мое намерение состояло не в том, чтобы получить имя столбца, а значение идентификатора. (Я сделал ошибку, это должно быть INSERT INTO pracownik (id, nr_ewid) values ​​($ Fields.KOMPETENCJA_ID, 'A'); но не меняет значения. Хорошо, поэтому компилятор делает встроенную константу времени copmile, и кажется невозможным иметь какую-либо константу в моей аннотации?

K2mil J33 25.12.2018 10:33

@ K2milJ33 Вы уловили идею, но давайте перефразируем ее правильно - значение атрибута аннотации должно быть постоянным. Вы можете использовать статическую конечную ссылку на переменную, но эта переменная также должна быть постоянной. Это означает, что его значение не может быть построено в результате вызова какого-либо конкретного метода, но должно быть определено встроенным. Это ограничение не относится к Groovy, а напрямую связано с Java.

Szymon Stepniak 25.12.2018 10:59

static class Fields {static final PRACOWNIK_ID = 1L static final TYP_ZADANIA_ID = 1L static final KOMPETENCJA_ID = 1L} var KOMPETENCJA_ID является постоянным ...

K2mil J33 27.12.2018 12:42

@ K2milJ33 Вы ошиблись в «Вы можете использовать статическую конечную ссылку на переменную, но эта переменная также должна быть постоянной».. Это означает, что вы можете создать постоянную строку в статическом конечном поле и использовать ее как @Sql(statements = myConstantStatement), где myConstantStatement - это не что иное, как постоянная строка. Однако в вашем случае вы добавляете константные строки к интерполированной GString, которая не является константной конструкцией. Такая же ошибка компиляции возникает, когда вы пытаетесь что-то вроде этого: @Sql(statements = String.format("--My SQL here--")). Не имеет значения, извлекается ли он в var

Szymon Stepniak 27.12.2018 14:11

Пример, в котором используется String.format(), также демонстрирует одно ограничение - для компилятора не имеет значения, использует ли строка, возвращаемая методом String.format(), какие-либо аргументы, такие как, например, String.format("Hello, %s", "John"). Постоянная строка - это всего лишь строка типа "Hello, John". Такие выражения, как String.format("Hello, John") или String.format("Hello, %s", "John"), не создают постоянных строк с точки зрения компилятора. А аннотации Java работают только с постоянными строками - вот почему вы также не можете использовать интерполированные строки Groovy.

Szymon Stepniak 27.12.2018 14:16

Спасибо, Шимон.

K2mil J33 27.12.2018 15:14

Другие вопросы по теме