Java Spring Data Mongodb-用于不同类型集合的存储库

Java Spring Data Mongodb-用于不同类型集合的存储库,java,spring,mongodb,spring-data,spring-data-mongodb,Java,Spring,Mongodb,Spring Data,Spring Data Mongodb,我有一个mongo集合,其中可能包含三种类型的实体,我将它们映射到java类型: 节点 叶型1 叶型2 集合用于使用父项中子节点的DBREF存储树状结构 我在Spring参考文档中没有找到任何关于主题的信息,所以我在这里问:有没有一种方法可以使用存储库机制来处理可能包含不同类型对象的集合 在一个集合中为不同的类型声明多个存储库似乎不是一个好主意,因为当查询的对象不是预期的类型时,我总是会遇到困难,而为抽象类创建一个存储库时,它中所有可能的类型似乎都不起作用 为了说明我的意思: /** *

我有一个mongo集合,其中可能包含三种类型的实体,我将它们映射到java类型:

  • 节点
  • 叶型1
  • 叶型2
集合用于使用父项中子节点的DBREF存储树状结构

我在Spring参考文档中没有找到任何关于主题的信息,所以我在这里问:有没有一种方法可以使用
存储库
机制来处理可能包含不同类型对象的集合

在一个集合中为不同的类型声明多个存储库似乎不是一个好主意,因为当查询的对象不是预期的类型时,我总是会遇到困难,而为抽象类创建一个存储库时,它中所有可能的类型似乎都不起作用

为了说明我的意思:

/**
 * 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> { }
/**
*这似乎不安全
*/
公共接口NodeRepository扩展了MongoRepository{}
公共接口LeafType1Repository扩展了MongoRepository{}
公共接口LeafType2Repository扩展了MongoRepository{}
/**
*这根本不起作用
*/
公共接口MyCollectionRepository扩展了MongoRepository{}

如果Node\LeafType1\LeafType2是AbstractMyCollectionNode的子类,那么事情就简单了。只需像您编写的那样声明存储库:

public interface MyCollectionRepository extends MongoRepository<AbstractMyCollectionNode, String> { }

存储库:

public interface DocumentDao extends MongoRepository<Document, String>{
...
公共接口文档DAO扩展了MongoRepository{
...
,如果mongodb集合中的文档没有“\u class”属性。您可以使用:

在存储和查询对象时,让MongoConverter实例处理所有Java类型到DBObjects的映射非常方便。但是,有时您可能希望“MongoConverter”完成大部分工作,但允许您有选择地处理特定类型的转换或优化性能


Spring数据在查找实体类时使用存储库声明作为入口点(它不会直接扫描包中的实体)

因此,您只需为子类声明一个“未使用”的存储库接口,就像您在OP中建议的“不安全”一样:

public interface NodeRepository extends MongoRepository<Node, String> { 
  // all of your repo methods go here
  Node findById(String id);
  Node findFirst100ByNodeType(String nodeType);
  ... etc.
}
public interface LeafType1Repository extends MongoRepository<LeafType1, String> {
  // leave empty
}
public interface LeafType2Repository extends MongoRepository<LeafType2, String> { 
  // leave empty
}
public interface NodeRepository扩展了MongoRepository{
//你所有的回购方法都在这里
节点findById(字符串id);
节点findFirst100ByNodeType(字符串nodeType);
等
}
公共接口LeafType1Repository扩展了MongoRepository{
//留空
}
公共接口LeafType2Repository扩展了MongoRepository{
//留空
}
您不必使用额外的
LeafTypeX
存储库,您可以使用
NodeRepository
来存储和查找
LeafType1
LeafType2
类型的对象。但是需要声明另外两个存储库,以便
LeafType1
LeafType2
将被禁用在进行初始扫描时作为实体找到


PS:当然,这一切都假设您拥有
@Document(collection=“nodes”)
在您的
LeafType1
LeafType2
类上添加了注释,但它不起作用。例如,如果我按id提取,我会得到一个错误,即无法直接实例化抽象对象。似乎以您建议的方式配置的存储库不知道使用哪个类来映射返回值。如果它适用于你能详细解释一下你的配置吗?@SimY4,我已经更新了答案。我想关键点可能是“\u类”属性。在阅读Spring数据引用并找到“转换器”后,我再次更新了答案。那么类型检查呢?您的存储库将返回类型为
Document
的对象。您是否总是对返回的类型执行检查以确定是否获得必需的输入?但您是否会丢失WebClipDocumen的字段T
public interface DocumentDao extends MongoRepository<Document, String>{
...
public interface NodeRepository extends MongoRepository<Node, String> { 
  // all of your repo methods go here
  Node findById(String id);
  Node findFirst100ByNodeType(String nodeType);
  ... etc.
}
public interface LeafType1Repository extends MongoRepository<LeafType1, String> {
  // leave empty
}
public interface LeafType2Repository extends MongoRepository<LeafType2, String> { 
  // leave empty
}