从 SDN+OGM 迁移到 SDN

已知的过去 SDN+OGM 迁移问题

SDN+OGM 过去几年经历了相当长的发展历程,我们深知将大型应用系统进行迁移既不轻松,也难以带来立竿见影的收益。我们在从 Spring Data Neo4j 的旧版本迁移到新版本过程中所观察到的主要问题,大致按以下顺序排列:spring-doc.cadn.net.cn

跳过了多次主要版本升级

虽然 Neo4j-OGM 可以独立使用,但 Spring Data Neo4j 不能。它在很大程度上依赖于 Spring Data,进而依赖于 Spring Framework 本身,这最终会影响您应用程序的大部分内容。根据应用程序的结构方式(即框架部分有多少渗透到您的业务代码中),您需要进行的适应性调整就越多。当您的应用程序中包含多个 Spring Data 模块时,情况会变得更糟;例如,如果您在同一服务层中同时访问关系型数据库和图数据库。同时更新两个对象映射框架并非一件愉快的事情。spring-doc.cadn.net.cn

依赖于通过 Spring Data 自身配置的嵌入式数据库

在 SDN+OGM 项目中,嵌入式数据库是通过 Neo4j-OGM 进行配置的。</p><p>假设您希望从 Neo4j 3.0 升级到 3.5,那么除非升级整个应用程序,否则无法实现。</p><p>为什么会这样呢?</p><p>由于您选择将数据库嵌入到应用程序中,就将自身绑定到了负责配置该嵌入式数据库的模块上。</p><p>若要使用另一个版本的嵌入式数据库,就必须升级负责配置它的模块,因为旧版本不支持新数据库。</p><p>由于始终存在与 Neo4j-OGM 对应的 Spring Data 版本,因此您也必须同时升级它。</p><p>然而,Spring Data 依赖于 Spring Framework,因此第一点中的论据同样适用于此。spring-doc.cadn.net.cn

不确定应包含哪些构建块

正确使用术语并不容易。我们在此处撰写了SDN+OGM设置的构建模块这里。也许这些组件恰好都被添加了,而您正面临大量相互冲突的依赖关系。spring-doc.cadn.net.cn

基于上述观察,我们建议您在将 SDN+OGM 迁移到 SDN 之前,确保当前应用程序仅使用 Bolt 或 HTTP 传输协议。</p><p>因此,您的应用程序及其访问层在很大程度上与数据库的版本解耦。</p><p>从这一状态出发,可考虑从 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 进行交互,这意味着在以下三种情况中的两种情况下工作:spring-doc.cadn.net.cn

您正在使用嵌入式环境

您已将 org.neo4j:neo4j-ogm-embedded-driverorg.neo4j:neo4j 添加到您的项目中,并通过 OGM 功能启动数据库。此操作已不再受支持,您必须设置一个标准的 Neo4j 服务器(支持独立模式和集群模式)。spring-doc.cadn.net.cn

上述依赖项必须删除。spring-doc.cadn.net.cn

从嵌入式解决方案迁移可能是最困难的迁移,因为您还需要设置一个服务器。然而,这也是最能体现自身价值的一种方式:未来,您可以在不考虑应用程序框架和数据访问框架的情况下,直接升级数据库本身。spring-doc.cadn.net.cn

您正在使用 HTTP 传输协议

您已添加 org.neo4j:neo4j-ogm-http-driver 并配置了一个类似 user:password@localhost:7474 的 URL。该依赖项必须替换为 org.neo4j:neo4j-ogm-bolt-driver,并且您需要配置一个类似 bolt://localhost:7687 的 Bolt URL,或使用新的 neo4j:// 方案,该方案同样负责路由。spring-doc.cadn.net.cn

您已经在间接使用 Bolt

一个默认的 SDN+OGM 项目使用 org.neo4j:neo4j-ogm-bolt-driver,从而间接地使用纯 Java 驱动程序。您可保留现有的 URL。spring-doc.cadn.net.cn

迁移

一旦您确认您的 SDN+OGM 应用程序已按预期在 Bolt 上正常运行,即可开始迁移至 SDN。spring-doc.cadn.net.cn

  • 移除所有 org.neo4j:neo4j-ogm-* 依赖项spring-doc.cadn.net.cn

  • 通过 org.neo4j.ogm.config.Configuration bean 配置 SDN 不被支持,取而代之的是,所有驱动程序的配置均通过我们的新 Java 驱动程序Starters完成。您尤其需要调整 URL 和身份验证相关的属性,请参阅 旧版与新版属性对比spring-doc.cadn.net.cn

您无法通过 XML 配置 SDN。</p><p>如果您在 SDN+OGM 应用程序中执行了此操作,请务必了解 Spring 应用程序的注解驱动或函数式配置方法。</p><p>如今最简便的选择是 Spring Boot。</p><p>在我们已设置好Starters的前提下,除了连接 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 的相关内容。spring-doc.cadn.net.cn

然后你就可以替换注解了:spring-doc.cadn.net.cn

org.neo4j.ogm.annotation.NodeEntityspring-doc.cadn.net.cn

org.springframework.data.neo4j.core.schema.Nodespring-doc.cadn.net.cn

org.neo4j.ogm.annotation.GeneratedValuespring-doc.cadn.net.cn

org.springframework.data.neo4j.core.schema.GeneratedValuespring-doc.cadn.net.cn

org.neo4j.ogm.annotation.Idspring-doc.cadn.net.cn

org.springframework.data.neo4j.core.schema.Idspring-doc.cadn.net.cn

org.neo4j.ogm.annotation.Propertyspring-doc.cadn.net.cn

org.springframework.data.neo4j.core.schema.Propertyspring-doc.cadn.net.cn

org.neo4j.ogm.annotation.Relationshipspring-doc.cadn.net.cn

org.springframework.data.neo4j.core.schema.Relationshipspring-doc.cadn.net.cn

org.springframework.data.neo4j.annotation.EnableBookmarkManagementspring-doc.cadn.net.cn

无需替换,不需要spring-doc.cadn.net.cn

org.springframework.data.neo4j.annotation.UseBookmarkspring-doc.cadn.net.cn

无需替换,不需要spring-doc.cadn.net.cn

org.springframework.data.neo4j.annotation.QueryResultspring-doc.cadn.net.cn

使用 投影;不再支持任意结果映射spring-doc.cadn.net.cn

若干 Neo4j-OGM 注解目前尚无对应的 Spring Data Neo4j (SDN) 注解,部分注解甚至可能永远不会存在。</p><p>随着我们支持更多功能,我们将持续更新上述列表。

书签管理

代码 @EnableBookmarkManagement@UseBookmark 以及 org.springframework.data.neo4j.bookmark.BookmarkManager 接口及其唯一实现类 org.springframework.data.neo4j.bookmark.CaffeineBookmarkManager 均已移除,不再需要。spring-doc.cadn.net.cn

SDN 使用书签进行所有事务,无需配置。
您也可以移除 CaffeineBookmarkManager 的 Bean 声明以及对 com.github.ben-manes.caffeine:caffeine 的依赖。spring-doc.cadn.net.cn

如果您确实必须这样做,可以通过遵循这些说明来禁用自动书签管理。spring-doc.cadn.net.cn

自动创建约束和索引

SDN 5.3 及更早版本提供了来自 Neo4j-OGM 的“自动索引管理器”。spring-doc.cadn.net.cn

@Index, @CompositeIndex and @Required 已被移除且未进行替换。
为什么?
我们认为,即使对于无模式数据库,创建模式也不属于领域建模的范畴。
你可能会争辩说,SDN 模型即为模式,但对此我们更倾向于采用 命令-查询分离(Command-query separation),
即我们更愿意分别定义读模型和写模型。
这些模型在编写“枯燥”的内容以及读取图结构结果时非常实用。spring-doc.cadn.net.cn

除此之外,某些注解及其值分别与特定的 Neo4j 版本或版本系列相关联,这使得它们难以维护。spring-doc.cadn.net.cn

然而,最有力的论点在于上线生产环境:尽管所有生成模式的工具在开发阶段确实很有帮助,尤其是对于那些强制执行严格模式的数据库,但在生产环境中它们往往不太友好:当您的应用程序不同版本同时运行时,您该如何处理?版本A是否应承认由较新版本B创建的索引?spring-doc.cadn.net.cn

我们认为最好提前掌控这一环节,并建议使用受控的数据库迁移,例如基于 LiquigraphNeo4j 迁移工具。后者已在 JHipster 项目中与 SDN(Spring Data Neo4j)配合使用。这两个项目共同的特点是:它们将当前的模式版本存储在数据库中,并确保在进行更新前,现有模式符合预期。spring-doc.cadn.net.cn

从先前的 Neo4j-OGM 注解迁移出去会影响 @Index@CompositeIndex@Required,此处提供了一个示例:在 一个使用 Neo4j-OGM 自动索引管理器的类 中。spring-doc.cadn.net.cn

一个利用 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;
}

其注解等效于 Neo4j 4.2 版本中 Cypher 的以下模式:spring-doc.cadn.net.cn

示例基于 Cypher 的迁移
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);

使用 @Index 而不使用 unique = true 等价于 CREATE INDEX movie_title_index FOR (m:Movie) ON (m.title)
请注意,唯一索引已隐含了索引。spring-doc.cadn.net.cn