此版本仍在开发中,尚不被认为是稳定的。对于最新的稳定版本,请使用 Spring Data Neo4j 7.5.2! |
从 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
并配置了一个 url,例如user:password@localhost:7474
.
依赖项必须替换为org.neo4j:neo4j-ogm-bolt-driver
并且您需要配置一个 Bolt url,例如bolt://localhost:7687
或使用新的neo4j://
scheme,它也负责路由。
迁移
一旦您确定您的 SDN+OGM 应用程序按预期在 Bolt 上工作,您就可以开始迁移到 SDN。
-
全部删除
org.neo4j:neo4j-ogm-*
依赖 -
通过配置 SDN
org.neo4j.ogm.config.Configuration
bean 不支持,而不是驱动程序的所有配置都通过我们新的 Java 驱动程序Starters。 您特别必须调整 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
以及对com.github.ben-manes.caffeine:caffeine
.
如果绝对必须,可以按照以下说明禁用自动书签管理。
自动创建约束和索引
SDN 5.3 及更早版本提供了 Neo4j-OGM 的“自动索引管理器”。
@Index
,@CompositeIndex
和@Required
已被移除而未更换。
为什么?
我们认为创建模式——即使是对于无模式数据库——也不是领域建模的一部分。
你可能会争辩说 SDN 模型是架构,但我们甚至更喜欢命令查询分离,
这意味着我们宁愿定义单独的读写模型。
这些对于写“无聊”的东西和阅读图形形状的答案非常方便。
除此之外,其中一些注释分别与特定的 Neo4j 版本或版本相关联,这使得它们 难以维护。
然而,最好的论据是进入生产环境:虽然所有生成模式的工具在开发过程中确实很有帮助,但对于强制执行严格方案的数据库更是如此, 它们在生产中往往不太好:如何处理同时运行的不同版本的应用程序? 版本 A 断言由较新版本 B 创建的索引?
我们认为最好预先控制这一点,并建议使用基于 Liquigraph 或 Neo4j 迁移等工具的受控数据库迁移。 后者已在 JHipster 项目中与 SDN 一起使用。 这两个项目的共同点是,它们将模式的当前版本存储在数据库中,并确保模式在更新之前符合预期。
从以前的 Neo4j-OGM 注释迁移会影响@Index
,@CompositeIndex
和@Required
这里在使用 Neo4j-OGM 自动索引管理器的 A 类中给出了一个示例:
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);
用@Index
没有unique = true
相当于CREATE INDEX movie_title_index FOR (m:Movie) ON (m.title)
.
请注意,唯一索引已经意味着索引。