2016-05-18 9 views
0

Я пытаюсь использовать последовательности для генерации инкрементированных идентификаторов для моих таблиц в 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(); 
    } 
} 
+0

Ваша установка говорит JPA, чтобы получить значение идентификатора из последовательности и использовать его во вставке. Я предполагаю, что это мешает вашему триггеру, который также устанавливает значение ID. Включите ведение журнала для вашего провайдера JPA и посмотрите инструкции, которые выполняются, чтобы определить, что не так, но я думаю, вы, вероятно, не должны использовать триггер в базе данных. Идентификация может работать, поскольку она сообщает провайдеру JPA искать значение последовательности, которое было установлено после выполнения инструкции insert, что соответствует тому, что делает ваш триггер. – Chris

+0

', но при использовании ebean утверждение не срабатывает' ... вы не говорите, что такое ошибка? Конечно, Ebean не ожидает, что курок будет там. Обратите внимание, что DB2 поддерживает как Identity, так и Sequences ... так что презумпция в том, что вы об этом подумали. –

+0

Это не Ebean - реализация JPA - она ​​использует аннотации JPA. Я удалю упоминание об этом, если это не так. Теперь я включил трассировку стека, но другой журнал не получил ничего примечательного. Я надеялся использовать тот же класс для OracleDB и DB2, поэтому я пытаюсь реализовать последовательности сгенерированных идентификаторов в DB2 –

ответ

1

Временный обходной путь для тех, кто заинтересован: в ebean.properties, установите

ebean.databaseSequenceBatchSize=1 

 Смежные вопросы

  • Нет связанных вопросов^_^