Я пытаюсь использовать последовательности для генерации инкрементированных идентификаторов для моих таблиц в DB2. Он работает, когда я отправляю операторы SQL непосредственно в базу данных, но при использовании ebean утверждение не выполняется. Вот поле в Java:Ebean Annotations - Использование последовательностей для генерации идентификаторов в DB2
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "TABLENAME_IDNAME_TRIG")
@SequenceGenerator(name = "TABLENAME_IDNAME_TRIG", sequenceName = "TABLENAME_IDNAME_SEQ")
@Column(name = "IDNAME")
private Long id;
Вот столбец в SQL (от ЖАБА):
Name Data type Not Null Default Generated Bit Data Scope Identity
IDNAME INTEGER Yes No No
А вот определение последовательности в SQL:
CREATE OR REPLACE SEQUENCE SCHEMA.TABLENAME_IDNAME_SEQ
AS INTEGER CACHE 50 ORDER;
И триггер:
CREATE OR REPLACE TRIGGER SCHEMA.TABLENAME_IDNAME_TRIG
NO CASCADE BEFORE INSERT
ON TABLENAME
REFERENCING
NEW AS OBJ
FOR EACH ROW
BEGIN
SET obj.IDNAME=NEXT VALUE FOR SCHEMA.TABLENAME_IDNAME_SEQ;
END;
В чем проблема с моим аннотации здесь? Как примечание (n важная) - когда я устанавливаю GenerationType в AUTO, TABLE или IDENTITY, он работает, хотя это и не должно, потому что я также использую этот объект для представления параллельной таблицы oracle, которая также использует последовательности для Генерация идентификаторов.
Отредактированных включить сообщение об ошибке:
javax.persistence.PersistenceException: Error getting sequence nextval
...
Caused by: com.ibm.db2.jcc.am.SqlSyntaxErrorException: DB2 SQL Error: SQLCODE=-348, SQLSTATE=428F9, SQLERRMC=NEXTVAL FOR SCHEMA.TABLENAME_IDNAME_SEQ, DRIVER=4.19.49
EDIT 2: Специфическое Sql заявления, которое является неисправным:
values nextval for QA_CONNECTION_ICONNECTIONI_SEQ union values nextval for QA_CONNECTION_ICONNECTIONI_SEQ union values nextval for QA_CONNECTION_ICONNECTIONI_SEQ
Какого SQL генерируется Ebean. Это небольшая версия реального оператора, которая повторяется 20 раз, поэтому я угадываю, что что-то прикручивает при генерации запроса кэширования.
РЕДАКТИРОВАТЬ 3: Я считаю, что это может быть ошибкой в использовании последовательностей DB2 в Ebean. Эта функция генерирует SQL, которая возвращает ошибку для меня при использовании db2
public DB2SequenceIdGenerator(BackgroundExecutor be, DataSource ds, String seqName, int batchSize) {
super(be, ds, seqName, batchSize);
this.baseSql = "values nextval for " + seqName;
this.unionBaseSql = " union " + baseSql;
}
EDIT 4: На основе этой SO ссылки, которую я думаю, что это ошибка. Can't insert multiple values into DB2 by using UNION ALL and generate IDs from sequence Правильный класс, вероятно, выглядит следующим образом? Хотя я никогда не пытался создать библиотеку, поэтому я не мог ее протестировать. Время, чтобы узнать, как открыть дефект, я думаю.
public class DB2SequenceIdGenerator extends SequenceIdGenerator {
private final String baseSql;
private final String unionBaseSql;
private final String startSql;
public DB2SequenceIdGenerator(BackgroundExecutor be, DataSource ds, String seqName, int batchSize) {
super(be, ds, seqName, batchSize);
this.startSql = "values "
this.baseSql = "(nextval for " + seqName);
this.unionBaseSql = ", " + baseSql;
}
public String getSql(int batchSize) {
StringBuilder sb = new StringBuilder();
sb.append(startSql);
sb.append(baseSql);
for (int i = 1; i < batchSize; i++) {
sb.append(unionBaseSql);
}
return sb.toString();
}
}
Ваша установка говорит JPA, чтобы получить значение идентификатора из последовательности и использовать его во вставке. Я предполагаю, что это мешает вашему триггеру, который также устанавливает значение ID. Включите ведение журнала для вашего провайдера JPA и посмотрите инструкции, которые выполняются, чтобы определить, что не так, но я думаю, вы, вероятно, не должны использовать триггер в базе данных. Идентификация может работать, поскольку она сообщает провайдеру JPA искать значение последовательности, которое было установлено после выполнения инструкции insert, что соответствует тому, что делает ваш триггер. – Chris
', но при использовании ebean утверждение не срабатывает' ... вы не говорите, что такое ошибка? Конечно, Ebean не ожидает, что курок будет там. Обратите внимание, что DB2 поддерживает как Identity, так и Sequences ... так что презумпция в том, что вы об этом подумали. –
Это не Ebean - реализация JPA - она использует аннотации JPA. Я удалю упоминание об этом, если это не так. Теперь я включил трассировку стека, но другой журнал не получил ничего примечательного. Я надеялся использовать тот же класс для OracleDB и DB2, поэтому я пытаюсь реализовать последовательности сгенерированных идентификаторов в DB2 –