【问题标题】:SD MongoDB polymorphism in subdocument子文档中的 SD MongoDB 多态性
【发布时间】:2013-01-30 23:21:43
【问题描述】:

我刚开始使用 spring-data-mongodb 用 Ja​​va 开发一些应用程序,遇到了一些我无法解决的问题:

有几个像这样的文档 bean:

@Document(collection="myBeanBar")
public class BarImpl implements Bar {
   String id;
   Foo foo;
   // More fields and methods ...
}

@Docuemnt
public class FooImpl implements Foo {
   String id;
   String someField;
   // some more fields and methods ...
}

我有一个存储库类,它的方法简单地调用类似于这样的查找:

public List<? extends Bar> findByFooField(final String fieldValue) {
    Query query = Query.query(Criteria.where("foo.someField").is(fieldValue));
    return getMongoOperations().find(query, BarImpl.class);
}

保存 Bar 效果很好,它将与 Foo 和 Bar 的“_class”属性一起保存在 mongo 中。但是,通过 Foo 中的某些属性查找会引发如下异常:

Exception in thread "main" java.lang.IllegalArgumentException: No property someField found on test.Foo!
    at org.springframework.data.mapping.context.AbstractMappingContext.getPersistentPropertyPath(AbstractMappingContext.java:225)
    at org.springframework.data.mongodb.core.convert.QueryMapper.getPath(QueryMapper.java:202)
    at org.springframework.data.mongodb.core.convert.QueryMapper.getTargetProperty(QueryMapper.java:190)
    at org.springframework.data.mongodb.core.convert.QueryMapper.getMappedObject(QueryMapper.java:86)
    at org.springframework.data.mongodb.core.MongoTemplate.doFind(MongoTemplate.java:1336)
    at org.springframework.data.mongodb.core.MongoTemplate.doFind(MongoTemplate.java:1322)
    at org.springframework.data.mongodb.core.MongoTemplate.find(MongoTemplate.java:495)
    at org.springframework.data.mongodb.core.MongoTemplate.find(MongoTemplate.java:486)

经过一番挖掘,这是有道理的,因为查询中没有指定子文档的具体类型,并且 Bar 的实体信息说 foo 的类型是 Foo(不是 FooImpl),这反过来可以没有属性,因为它是一个接口。

我的问题是:有没有办法在不将子文档类型声明为具体类型的情况下指定它或解决此问题?

我已经在谷歌上搜索了几天,查看了文档和 API 以及源代码,但我找不到明确的方法。非常感谢您的帮助。

非常感谢。

【问题讨论】:

  • 经过更多测试,我注意到当我保存一个对象然后从 mongodb 检索文档时,一切正常。但是,当它是第一次从 MongoDB 读取时,我得到一个 BeanInstantiationException。显然 objectCallback 没有适当的 TypeMapper 可以将接口解析为具体类以实例化 DBObject。

标签: spring mongodb polymorphism spring-data-mongodb


【解决方案1】:

我遇到了类似的问题,我有一个实现接口的类,当我使用findAll 时出现错误:

org.springframework.data.mapping.model.MappingInstantiationException: 无法实例化 bean 类 [test.MetaClasse]: 指定的类是一个接口。

调试SpringData 代码后,我意识到Mapper 使用@TypeAlias 来发现它必须实例化的类型,所以我只是将@TypeAlias("FullClassName") 放在我的test.MetaClasse 实现上,它就起作用了!

我测试了你的情况,它会起作用的!

【讨论】:

  • 此解决方案是否有替代方案?从设计的角度来看,这似乎很糟糕。您必须为 Foo 的每个实现添加一个 @TypeAlias 注释。
  • 此外,这种方法使重构变得非常困难。如果我需要重命名一个类怎么办?数据库中的所有 _alias 引用现在都没有用了。如果我需要创建一个类抽象然后添加子实现怎么办?再一次, _alias 引用现在没用了。我必须编写一个脚本来遍历数据并全部更改。必须有更好的解决方案。
猜你喜欢
  • 2015-07-08
  • 2014-09-27
  • 1970-01-01
  • 2015-07-23
  • 1970-01-01
  • 1970-01-01
  • 2023-03-28
  • 1970-01-01
  • 2014-09-28
相关资源
最近更新 更多