Можно ли скомпилировать отличный код, где у меня есть аннотация @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 в многострочной строке?




Проблема, с которой вы столкнулись, не имеет ничего общего с многострочным 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 representGStringtype. However, Groovy compiler checks if the string contains any variables like${variableName}to do the interpolation. If it finds any, it usesGStringas a type, andStringotherwise.
@ K2milJ33 Вы уловили идею, но давайте перефразируем ее правильно - значение атрибута аннотации должно быть постоянным. Вы можете использовать статическую конечную ссылку на переменную, но эта переменная также должна быть постоянной. Это означает, что его значение не может быть построено в результате вызова какого-либо конкретного метода, но должно быть определено встроенным. Это ограничение не относится к Groovy, а напрямую связано с Java.
static class Fields {static final PRACOWNIK_ID = 1L static final TYP_ZADANIA_ID = 1L static final KOMPETENCJA_ID = 1L} var KOMPETENCJA_ID является постоянным ...
@ K2milJ33 Вы ошиблись в «Вы можете использовать статическую конечную ссылку на переменную, но эта переменная также должна быть постоянной».. Это означает, что вы можете создать постоянную строку в статическом конечном поле и использовать ее как @Sql(statements = myConstantStatement), где myConstantStatement - это не что иное, как постоянная строка. Однако в вашем случае вы добавляете константные строки к интерполированной GString, которая не является константной конструкцией. Такая же ошибка компиляции возникает, когда вы пытаетесь что-то вроде этого: @Sql(statements = String.format("--My SQL here--")). Не имеет значения, извлекается ли он в var
Пример, в котором используется String.format(), также демонстрирует одно ограничение - для компилятора не имеет значения, использует ли строка, возвращаемая методом String.format(), какие-либо аргументы, такие как, например, String.format("Hello, %s", "John"). Постоянная строка - это всего лишь строка типа "Hello, John". Такие выражения, как String.format("Hello, John") или String.format("Hello, %s", "John"), не создают постоянных строк с точки зрения компилятора. А аннотации Java работают только с постоянными строками - вот почему вы также не можете использовать интерполированные строки Groovy.
Спасибо, Шимон.
Привет, Мое намерение состояло не в том, чтобы получить имя столбца, а значение идентификатора. (Я сделал ошибку, это должно быть INSERT INTO pracownik (id, nr_ewid) values ($ Fields.KOMPETENCJA_ID, 'A'); но не меняет значения. Хорошо, поэтому компилятор делает встроенную константу времени copmile, и кажется невозможным иметь какую-либо константу в моей аннотации?