我試圖使用序列爲DB2中的表生成增量ID。它將SQL語句直接發送到數據庫時有效,但在使用ebean時,語句失敗。以下是一個Java領域:Ebean註解 - 在DB2中使用序列生成ID
@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;
我的問題是什麼註釋在這裏?作爲一個(重要的)附註 - 當我將GenerationType設置爲AUTO,TABLE或IDENTITY時,它可以工作,即使它不應該,因爲我也使用這個對象來表示並行oracle表,它也使用序列ID生成。
編輯,包括錯誤消息:
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
編輯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
這是由Ebean生成的SQL。這是真實陳述的一個較小版本,它重複了20次,所以我在猜測生成緩存查詢時遇到的問題。編輯3:我相信這可能是Ebean使用DB2序列時的一個錯誤。這個函數生成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值和插件內使用它。我猜這是干擾你的觸發器,也是設置ID值。打開JPA提供程序的日誌記錄並查看正在執行的語句以確定錯誤,但我認爲您應該不要在數據庫中使用觸發器。標識可能正在工作,因爲它告訴JPA提供程序查詢插入語句執行後設置的序列值,這與您的觸發器正在執行的操作相匹配。 – Chris
'但是當使用ebean時,語句失敗......你不說錯誤是什麼?當然,Ebean並不期待觸發器在那裏。請注意,DB2支持Identity和Sequences ...因此推測是你已經考慮過了。 –
不是Ebean是JPA的實現 - 它使用JPA註釋。如果不是,我會刪除提及。現在我已經包含了堆棧跟蹤,但其他日誌記錄沒有返回任何值得注意的事情。 我一直希望爲OracleDB和DB2使用相同的類,這就是爲什麼我試圖在DB2中實現序列生成ID –