首页 文章

Spring Data MongoDB模板转换为错误的类

提问于
浏览
0

使用Spring 5.0.6和Spring-Data-Mongo 2.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集合存储两种类型的 User ,由自动添加的_class属性区分 .

此外,还有一个注册了MongoTemplate的Repository .

@Autowired 
private org.springframework.data.mongodb.core.MongoTemplate template;

一切都很好,到目前为止 . 现在,如果我想获取包含 RealUser 的所有文档,我可以调用它

template.findAll(RealUser.class)

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

但这并不像预期的那样有效 . 我甚至得到了所有 VirtualUser ,并且放入了 RealUser 类型的对象,其中缺少所有特定于VirtualUser的属性,并且所有特定于RealUser的属性都设置为 null .

此外,当我去保存一个 User ,它实际上是MongoDB中的 VirtualUser ,但已被挤入 RealUser 类时,Spring会将 _class -property更改为错误类型,将 VirtualUser 神奇地转换为 RealUser .

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

template.findAll(VirtualUser.class)
 template.findAll(RealUser.class)

这种行为可能是不希望的,或者如果是这样的话,那就极具误导性和危害性 . 您可以使用此功能轻松切碎整个数据 .

任何人都可以对此有所了解吗?

1 回答

  • 1

    我在Spring的Jira创建了一个ticket . 在下面找到Olivers评论:

    该方法实际上按预期工作,但我同意我们需要改进JavaDoc . 该方法基本上被指定为“将给定类型配置为持久化的文档加载并将所有这些文档(因此名称)映射到给定类型” . 给定的类型不会同时用作类型映射标准 . 您要对返回的文档应用的每个限制都需要通过Query实例应用,该实例公开了一个... .restrict(...)方法,该方法只允许选择带有类型信息的文档 . findAll以其工作方式工作的原因是,一般来说 - 即没有继承方案 - 我们需要能够读取所有文档,即使它们不携带任何类型信息 . 假设一个集合包含代表未使用Spring Data编写的人员的文档 . 如果findAll(Person.class)应用了类型限制,即使存在文档,调用也不会返回任何文档 . 不幸的是,我们不知道要查询的集合是否包含类型信息 . 事实上,有些文件可能带有类型信息,有些可能没有 . 合理控制它的唯一方法是让用户决定,她可以通过调用Query.restrict(...)来决定 . 前者仅选择具有类型信息的文档,后者 . 正如我所说,我完全看到JavaDoc可能会误导这里 . 我要用这张票来改进 . 很想知道Query.restict(...)的使用是否可以让你实现你想要的 .

相关问题