試圖使我的 Spring Boot JPA 應用程式與 Oracle DB 兼容,已經在 MySQL 和 H2 上運行。不幸的是,liquibase 生成的資料使用了一些 Oracle 的保留關鍵字作為表名或列名。
好訊息是 hibernate 和 liquibase 實作可以檢測這些關鍵字并在查詢資料庫時“參考”它們(objectQuotingStrategy="QUOTE_ONLY_RESERVED_KEYWORDS"用于 liquibase 和spring.jpa.properties.hibernate.auto_quote_keyword: truehibernate)。壞訊息是 hibernate 和 liquibase 不共享相同的 Oracle 保留關鍵字串列。
例如,liquibase 不將value識別為保留關鍵字,但 hibernate(使用 ANSI SQL:2003 關鍵字)將其識別為保留關鍵字。我的一個liquibase變更的創建具有較低情況下的表值列,因此Liquibase與無引號小寫創建表值列和Oracle DB中的上殼體自動地打開它VALUE柱。現在,當 hibernate 嘗試獲取該列時,它會識別值并參考它(`SELECT "value" from ...),這使得它區分大小寫,因此找不到該列 (ORA-00904)。
我想我通過擴展 SpringLiquibase 并添加我的自定義關鍵字找到了解決方法,如下所述:https ://liquibase.jira.com/browse/CORE-3324 。問題是這似乎不適用于OracleDatabase實作,它覆寫了 SpringLiquibase 的保留關鍵字集(當然,該isReservedWord()方法使用了 OracleDatabase 的集)。
現在,我將使用QUOTE_ALL_OBJECTSliquibase 和hibernate.globally_quoted_identifiers.
但是,出于好奇,我想知道是否可以附加 liquibase for Oracle 使用的一組保留關鍵字。
- 彈簧引導版本:2.3.9.RELEASE。
- hibernate-core 版本(spring boot 依賴):5.4.28
- liquibase-core 版本(spring boot 依賴):3.8.9
uj5u.com熱心網友回復:
嗯,在 Oracle 的情況下,您有關鍵字和保留字。
- 保留字不能用作識別符號
- 關鍵字可以用作識別符號,但不推薦使用。
您可以直接從資料庫中獲取它們的串列:
select KEYWORD, RESERVED from v$reserved_words;
...
1864 rows selected
在源代碼中到處使用大寫名稱怎么樣?
看起來 Liqubase 在功能上依賴于某些 JDBC 驅動程式 - 這不起作用。
甲骨文資料庫.java :
public void setConnection(DatabaseConnection conn) {
//noinspection HardCodedStringLiteral,HardCodedStringLiteral,HardCodedStringLiteral,HardCodedStringLiteral,
// HardCodedStringLiteral
reservedWords.addAll(Arrays.asList("GROUP", "USER", "SESSION", "PASSWORD", "RESOURCE", "START", "SIZE", "UID", "DESC", "ORDER")); //more reserved words not returned by driver
Connection sqlConn = null;
if (!(conn instanceof OfflineConnection)) {
try {
/*
* Don't try to call getWrappedConnection if the conn instance is
* is not a JdbcConnection. This happens for OfflineConnection.
* see https://liquibase.jira.com/browse/CORE-2192
*/
if (conn instanceof JdbcConnection) {
sqlConn = ((JdbcConnection) conn).getWrappedConnection();
}
} catch (Exception e) {
throw new UnexpectedLiquibaseException(e);
}
if (sqlConn != null) {
tryProxySession(conn.getURL(), sqlConn);
try {
//noinspection HardCodedStringLiteral
reservedWords.addAll(Arrays.asList(sqlConn.getMetaData().getSQLKeywords().toUpperCase().split(",\\s*")));
} catch (SQLException e) {
//noinspection HardCodedStringLiteral
Scope.getCurrentScope().getLog(getClass()).info("Could get sql keywords on OracleDatabase: " e.getMessage());
//can not get keywords. Continue on
}
如果 Liquibase 呼叫 sqlConn.getMetaData().getSQLKeywords() 并且這沒有回傳正確的輸出,那么您的機會是有限的。這可能是 JDBC 驅動程式中的錯誤,或者您的應用程式沒有 SELECT_CATALOG_ROLE 權限并且看不到v$reserved_words視圖(如果 JDBC 在內部查詢)。
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/311338.html
