举一个例子:我想在MongoDB中保留一些实体,在Cassandra中保留一些实体。
我的存储库接口扩展了CrudRepository
。我的Cassandra实体有@Table
,我的MongoDb实体有@Document
个注释。
但是,在启动时,spring-data尝试创建MyMongoObjectRepository
的实例,因此抱怨“Cassandra实体必须具有@ Table,@ Persistent或@PrimaryKeyClass注释”。
库如何发现它们应该实现哪些存储库接口,以及如何控制它们以便它们不会尝试为不受支持的实体实现它们?
进一步的问题:如果我想在两个存储系统中存储一些实体,可以生成单个存储库的多个实现,还是每个商店都需要一个接口?
修改
在进一步检查时,问题似乎来自实体扫描而不是存储库扫描。两个映射器都会获取所有实体(因为它们的注释都扩展为@Persistent
)。其中一个Mongo实体有一个Cassandra映射器无法处理的嵌套实体(没有任何注释)。
答案 0 :(得分:2)
您可以使用@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等事务的db。
答案 1 :(得分:0)
问题是所有不同的实体扫描程序都使用@Persistent
作为他们正在寻找的注释,而所有特定于repo的注释(@Table
,@Document
等)也是如此将@Persistent
作为元注释。
因此,不同存储库的实体必须位于不同的包中,您必须构建自己的扫描程序才能将包传递给它,因为它不接受通用过滤器。