從 SDN+OGM 遷移到 SDN
過去 SDN+OGM 遷移的已知問題
多年來,SDN+OGM 經歷了相當長的歷史,我們理解遷移大型應用系統既不好玩,也不會立即帶來利潤。我們在從舊版 Spring Data Neo4j 遷移到新版時觀察到的主要問題大致如下:
- 跳過多次主要升級
-
雖然 Neo4j-OGM 可以單獨使用,但 Spring Data Neo4j 不能。它很大程度上取決於 Spring Data,因此也取決於 Spring Framework 本身,這最終會影響您應用程式的很大一部分。取決於應用程式的結構,也就是說,框架的任何部分洩漏到您的業務程式碼中的程度,您就必須調整您的應用程式越多。如果您在應用程式中有一個以上的 Spring Data 模組,如果您在與圖形資料庫相同的服務層中存取關聯式資料庫,情況會更糟。更新兩個物件映射框架並不好玩。
- 依賴透過 Spring Data 本身設定的嵌入式資料庫
-
SDN+OGM 專案中的嵌入式資料庫由 Neo4j-OGM 設定。假設您想從 Neo4j 3.0 升級到 3.5,您無法在不升級整個應用程式的情況下進行。為什麼會這樣?由於您選擇將資料庫嵌入到應用程式中,因此您將自己綁定到設定此嵌入式資料庫的模組。若要擁有另一個嵌入式資料庫版本,您必須升級設定它的模組,因為舊模組不支援新資料庫。由於始終存在與 Neo4j-OGM 對應的 Spring Data 版本,因此您也必須升級它。然而,Spring Data 取決於 Spring Framework,然後第一個要點中的論點適用。
- 不確定要包含哪些建構區塊
-
正確理解術語並不容易。我們在這裡 寫了 SDN+OGM 設定的建構區塊。可能所有這些都是偶然添加的,並且您正在處理許多衝突的相依性。
基於這些觀察,我們建議在從 SDN+OGM 切換到 SDN 之前,請確保您目前的應用程式中僅使用 Bolt 或 http 傳輸。因此,您的應用程式和應用程式的存取層在很大程度上獨立於資料庫的版本。從該狀態開始,考慮從 SDN+OGM 遷移到 SDN。 |
準備從 SDN+OGM Lovelace 或 SDN+OGM Moore 遷移到 SDN
Lovelace 版本列車對應於 SDN 5.1.x 和 OGM 3.1.x,而 Moore 則是 SDN 5.2.x 和 OGM 3.2.x。 |
首先,您必須確保您的應用程式透過 Bolt 通訊協定在伺服器模式下針對 Neo4j 執行,這表示在三種情況中有兩種情況下需要進行工作
您正在使用嵌入式
您已將 org.neo4j:neo4j-ogm-embedded-driver
和 org.neo4j:neo4j
新增至您的專案,並透過 OGM 功能啟動資料庫。這不再受支援,您必須設定標準 Neo4j 伺服器(同時支援獨立和叢集)。
上述相依性必須移除。
從嵌入式解決方案遷移可能是最困難的遷移,因為您也需要設定伺服器。然而,這是在未來為您帶來巨大價值的遷移:在未來,您將能夠升級資料庫本身,而無需考慮您的應用程式框架和資料存取框架。
您正在使用 HTTP 傳輸
您已新增 org.neo4j:neo4j-ogm-http-driver
並設定類似 user:password@localhost:7474
的 URL。相依性必須替換為 org.neo4j:neo4j-ogm-bolt-driver
,並且您需要設定 Bolt URL,例如 bolt://localhost:7687
或使用新的 neo4j://
方案,該方案也負責路由。
遷移
一旦您確定您的 SDN+OGM 應用程式如預期般透過 Bolt 運作,您就可以開始遷移到 SDN。
-
移除所有
org.neo4j:neo4j-ogm-*
相依性 -
不支援透過
org.neo4j.ogm.config.Configuration
bean 設定 SDN,而是所有驅動程式的設定都透過我們新的 Java 驅動程式啟動器進行。您尤其必須調整 url 和驗證的屬性,請參閱 新舊屬性比較
您無法透過 XML 設定 SDN。如果您使用 SDN+OGM 應用程式執行此操作,請確保您了解 Spring 應用程式的註解驅動或功能性設定。目前最簡單的選擇是 Spring Boot。透過我們的啟動器,除了連線 URL 和驗證之外,所有必要的位元都已為您設定完成。 |
# Old
spring.data.neo4j.embedded.enabled=false # No longer supported
spring.data.neo4j.uri=bolt://localhost:7687
spring.data.neo4j.username=neo4j
spring.data.neo4j.password=secret
# New
spring.neo4j.uri=bolt://localhost:7687
spring.neo4j.authentication.username=neo4j
spring.neo4j.authentication.password=secret
當 SDN 和驅動程式最終完全取代舊設定時,這些新屬性未來可能會再次變更。 |
最後,新增新的相依性,請參閱 開始使用,了解 Gradle 和 Maven 的資訊。
然後您就可以準備替換註解
舊 | 新 |
---|---|
|
|
|
|
|
|
|
|
|
|
|
無替代方案,不需要 |
|
無替代方案,不需要 |
|
使用投影;不再支援任意結果映射 |
幾個 Neo4j-OGM 註解在 SDN 中尚未有對應的註解,有些永遠不會有。當我們支援其他功能時,我們會將其新增到上面的清單中。 |
書籤管理
@EnableBookmarkManagement
和 @UseBookmark
以及 org.springframework.data.neo4j.bookmark.BookmarkManager
介面及其唯一實作 org.springframework.data.neo4j.bookmark.CaffeineBookmarkManager
都已消失,並且不再需要。
SDN 將書籤用於所有交易,無需設定。您可以移除 CaffeineBookmarkManager
的 bean 宣告以及對 com.github.ben-manes.caffeine:caffeine
的相依性。
如果您絕對需要,您可以按照這些指示停用自動書籤管理。
自動建立約束和索引
SDN 5.3 和更早版本提供了 Neo4j-OGM 中的「自動索引管理器」。
@Index
、@CompositeIndex
和 @Required
已移除,沒有替代方案。為什麼?我們認為,即使對於無結構描述的資料庫,建立結構描述也不是網域模型設計的一部分。您可能會爭辯說 SDN 模型就是結構描述,但我們會回答說,我們甚至更喜歡 命令查詢分離,這意味著我們寧願定義單獨的讀取和寫入模型。這些對於編寫「枯燥」的東西和讀取圖形狀的答案非常方便。
除此之外,其中一些註解分別對應的值與特定的 Neo4j 版本或版本相關聯,這使得它們難以維護。
然而,最好的論點是投入生產:雖然所有產生結構描述的工具在開發期間確實很有幫助,對於強制執行嚴格方案的資料庫更是如此,但它們在生產中往往不太好:您如何處理同時運行的應用程式的不同版本?版本 A 斷言由較新版本 B 建立的索引?
我們認為最好預先控制此問題,並建議使用受控制的資料庫遷移,基於像 Liquigraph 或 Neo4j migrations 這樣的工具。後者已在 JHipster 專案中與 SDN 一起使用。這兩個專案的共同點是,它們將結構描述的目前版本儲存在資料庫中,並確保結構描述符合預期,然後才會更新內容。
從先前的 Neo4j-OGM 註解遷移會影響 @Index
、@CompositeIndex
和 @Required
,此處的 使用 Neo4j-OGM 自動索引管理器的類別 中提供了一個範例
import org.neo4j.ogm.annotation.CompositeIndex;
import org.neo4j.ogm.annotation.GeneratedValue;
import org.neo4j.ogm.annotation.Id;
import org.neo4j.ogm.annotation.Index;
import org.neo4j.ogm.annotation.Required;
@CompositeIndex(properties = {"tagline", "released"})
public class Movie {
@Id @GeneratedValue Long id;
@Index(unique = true)
private String title;
private String description;
private String tagline;
@Required
private Integer released;
}
它的註解等效於 Cypher 中的以下方案(截至 Neo4j 4.2)
CREATE CONSTRAINT movies_unique_title ON (m:Movie) ASSERT m.title IS UNIQUE;
CREATE CONSTRAINT movies_released_exists ON (m:Movie) ASSERT EXISTS (m.released);
CREATE INDEX movies_tagline_released_idx FOR (m:Movie) ON (m.tagline, m.released);
不使用 unique = true
的 @Index
等效於 CREATE INDEX movie_title_index FOR (m:Movie) ON (m.title)
。請注意,唯一索引已經暗示索引。