【问题标题】:How to use multiple spring-boot-starter-data-* dependencies如何使用多个 spring-boot-starter-data-* 依赖项
【发布时间】:2016-04-09 06:14:52
【问题描述】:

举个例子:我希望一些实体在 MongoDB 中持久化,一些在 Cassandra 中。 我的存储库接口扩展了CrudRepository。我的 Cassandra 实体有 @Table,我的 MongoDb 实体有 @Document 注释。

但是,在启动时,spring-data 会尝试创建 MyMongoObjectRepository 的实例,因此会抱怨“Cassandra 实体必须具有 @Table、@Persistent 或 @PrimaryKeyClass 注释”。

这些库如何发现它们应该实现的存储库接口,以及我如何控制它们以便它们不会尝试为不受支持的实体实现它们?

进一步的问题:如果我想在两个存储系统中存储一些实体,是否可以生成单个存储库的多个实现,或者我是否需要每个存储的接口?

编辑 进一步检查,问题似乎来自实体扫描而不是存储库扫描。两个映射器都拾取所有实体(因为它们的注释都扩展了@Persistent)。其中一个 Mongo 实体有一个 Cassandra 映射器无法处理的嵌套实体(没有任何注释)。

【问题讨论】:

  • 据我了解,您可以将 mongo/cassandra 存储库放在单独的包中,并使用 @EnableMongoRepositories@EnableJpaRepositories 在适当的包中查找存储库。

标签: spring-boot spring-data


【解决方案1】:

您可以在@EnableMongoRepositories 和@EnableJpaRepositories 中使用basePackages 设置来指定它们应在何处查找存储库定义。

像这样:

@EnableMongoRepositories(basePackages={
        "com.some.package.to.look.inside",
        "com.some.package.to.look.also.at"
})

@EnableJpaRepositories(basePackages={
        "com.some.differentpackage.to.look.inside",
        "com.some.differentpackage.to.look.also.at"
})

为此,您需要在合理的包中命名您的存储库定义。

回答您的后续问题:

如果您想一次将实体存储在多个位置,我将在存储库前实现一个服务,利用@Autowire 依赖注入存储库并在调用存储库方法的服务方法上设置@Transactional。在服务方法上使用 @Transactional 可确保如果在保存时发生错误,它将确保不会留下中途保存,甚至在必要时进行回滚。

编辑:

@Transactional 不适用于不支持 Cassandra 和 MongoDB 等事务的数据库。

【讨论】:

  • MongoDB 和 Cassandra 都不支持事务,但对于支持事务的系统来说是一个很好的提示。
  • 感谢您的信息。我在我的答案中添加了一个编辑。我的回答是否以某种方式解决了您的问题。还是还有未解决的问题?
  • 存储库不需要位于单独的包中,因为 @EnableXRepositories 注释也接受过滤器。解决方案是将实体放在单独的包中,因为实体扫描仪不支持过滤器。
【解决方案2】:

问题是所有不同的实体扫描器都使用 @Persistent 作为他们正在寻找的注释,而所有特定于 repo 的注释(@Table@Document 等)也有 @Persistent 作为元注释。

因此,不同存储库的实体必须位于单独的包中,并且您必须构建自己的扫描仪才能将包传递给它,因为它不接受通用过滤器。

【讨论】:

    猜你喜欢
    • 2015-12-28
    • 2018-03-01
    • 2016-06-21
    • 2017-07-24
    • 1970-01-01
    • 2017-03-19
    • 2021-07-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多