我有一个mongo集合,可能包含三种类型的实体,我映射到java类型:
-
节点
-
LeafType1
-
LeafType2
集合是使用父条目中的子节点的dbRefs来存储树状结构 .
我没有问这里:有没有办法使用 Repository
机制来处理可能包含不同类型对象的集合?
在一个集合中为不同类型声明几个存储库似乎不是一个好主意,因为当查询对象不是预期类型并且为抽象类创建一个所有可能类型继承似乎不起作用的存储库时,我总是很难处理 .
说明我的意思:
/**
* This seems not safe
*/
public interface NodeRepository extends MongoRepository<Node, String> { }
public interface LeafType1Repository extends MongoRepository<LeafType1, String> { }
public interface LeafType2Repository extends MongoRepository<LeafType2, String> { }
/**
* This doesn't work at all
*/
public interface MyCollectionRepository extends MongoRepository<AbstractMyCollectionNode, String> { }
2 回答
如果Node \ LeafType1 \ LeafType2是AbstractMyCollectionNode的子类,那么事情就很容易了 . 只需像你写的那样声明存储库:
我们在一个项目中完成了这项工作,并且效果很好 . Spring Data会将名为'_class'的属性添加到mongodb集合中的文档中,以便它可以指出要实例化的类 .
存储在一个集合中的文档可能有一些相似之处,也许您可以为它们提取一个通用类 .
以下是从我们的一个项目中复制的一些代码:
实体:
库:
And ,如果您在mongodb集合中的文档没有"_class"属性 . 你可以使用Converter:
在查找实体类时,Spring数据使用Repository-Declarations作为入口点(它不直接扫描实体的包) .
因此,您需要做的就是为您的子类声明一个“未使用的”存储库接口,就像您在OP中提出的“不安全”一样:
您不必使用额外的
LeafTypeX
存储库,您可以使用NodeRepository
来存储和查找LeafType1
和LeafType2
类型的对象 . 但是需要声明其他两个存储库,以便在初始扫描发生时将LeafType1
和LeafType2
作为实体找到 .PS:当然,这一切都假定您在
LeafType1
和LeafType2
类上有@Document(collection= "nodes")
注释