Java Spring数据MongoDB模板转换为错误的类

Java Spring数据MongoDB模板转换为错误的类,java,spring,mongodb,spring-data-mongodb,Java,Spring,Mongodb,Spring Data Mongodb,使用Spring5.0.6和SpringDataMongo2.0.7,我在获取转换到错误类的实体时遇到了一个问题。请参见以下简化场景: 实体设置: public class PersistableObject { @Id @Field("_id") private String id; } @Document(collection = "myapp_user") public class User extends PersistableObject {...} public class

使用Spring5.0.6和SpringDataMongo2.0.7,我在获取转换到错误类的实体时遇到了一个问题。请参见以下简化场景:

实体设置:

public class PersistableObject {
  @Id @Field("_id") private String id; 
}

@Document(collection = "myapp_user")
public class User extends PersistableObject {...}

public class RealUser extends User {...}

public class VirtualUser extends User {...}
因此,有一个公共MongoDB集合存储两种类型的
用户
,通过自动添加的_class属性进行区分

此外,还有一个存储库,MongoTemplate被注入其中

@Autowired 
private org.springframework.data.mongodb.core.MongoTemplate template;
到目前为止一切都很好。现在,如果我想获取包含
RealUser
的所有文档,我可以调用

template.findAll(RealUser.class)
我希望模板能够找到所有将discriminator属性_class设置为
com.myapp.domain.RealUser
的文档

但这并不像预期的那样有效。我甚至还将所有的
VirtualUser
s放入
RealUser
类型的对象中,所有virtualser特定的属性都丢失,所有RealUser特定的属性都设置为
null

此外,当我去保存一个
用户
,它实际上是MongoDB中的一个
虚拟用户
,但被压缩到
RealUser
类中时,Spring会将
\u类
-属性更改为错误的类型,神奇地将
虚拟用户
转换为
RealUser

因此,这里的两个方法都会加载整个集合并将所有对象压缩到指定的类中,即使该类是错误的:

 template.findAll(VirtualUser.class)
 template.findAll(RealUser.class)
这种行为可能是不可取的,或者如果是这样,那么它是极其误导和有害的。你可以很容易地用这个撕碎你的全部数据

有人能解释一下吗?

我在春季的Jira上创建了一个。请在下面查找Olivers的评论:

这个方法实际上和预期的一样有效,但我同意我们需要这样做 改进JavaDoc。该方法基本上规定为“加载 将给定类型的文档配置为持久化并映射所有 将它们(因此得名)转换为给定类型”。指定给它的类型不是 同时用作类型映射条件。每一项限制 您要对返回的文档进行应用,需要对其进行应用 通过一个查询实例,该实例公开了一个 仅允许选择包含类型信息的文档

findAll以这种方式工作的原因是 比如说,在没有继承场景的情况下,我们需要 能够阅读所有文档,即使它们没有任何类型 信息。假设集合中包含代表人员的文档 尚未使用Spring数据写入的。如果 findAll(Person.class)应用了类型限制,调用将返回 即使存在文件,也没有文件。不幸的是我们 不知道将要查询的集合是否包含类型 信息。事实上,有些文档可能包含类型信息, 有些人可能不会。合理控制这种情况的唯一方法是让 用户可以通过调用Query.restrict(…)或not来决定。 前者选择仅包含类型信息的文档,后者选择包含类型信息的文档

正如我所说的,我完全明白JavaDoc在这里可能有误导性。 我要用这张票来改善这一点。我很想知道 使用Query.restict(…)可以实现您想要的