子文档中的 SD MongoDB 多态性 [英] SD MongoDB polymorphism in subdocument

查看:20
本文介绍了子文档中的 SD MongoDB 多态性的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I just started developing some app in Java with spring-data-mongodb and came across some issue that I haven't been able to solve:

有几个像这样的文档 bean:

Have a couple of document beans like this:

@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 ...
}

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

And I have a repository class with a method that simply invokes a find similar to this:

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 中的某些属性查找会引发如下异常:

Saving a Bar works just fine, it would save it in mongo along with the "_class" attribute for both Foo and Bar. However, finding by some attribute in Foo would throw an exception like this:

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),这反过来可以没有属性,因为它是一个接口.

Which, after some digging, makes some sense, since nowhere in the query is the sub-document concrete type being specified, and the Entity Information of Bar says the type of foo is Foo (not FooImpl), which in turn can not have properties cause it is an interface.

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

My question is: Is there a way to specify it or work-around this issue without declaring the sub-document type as a concrete type?

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

I've been googling it for a couple of days and looking at the documentation and API and the source code but I can not find a clear way to do it. I'd really appreciate your help.

非常感谢.

推荐答案

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

I had a similar problem, I have a class that implements an interface and when I use findAll I get the error:

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

org.springframework.data.mapping.model.MappingInstantiationException: Could not instantiate bean class [test.MetaClasse]: Specified class is an interface.

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

After debugging SpringData code, I realized that Mapper uses @TypeAlias to discover the type it has to instantiate, so I just put @TypeAlias("FullClassName") on my implementations of test.MetaClasse and it worked!

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

I tested with your situation and it will work!

这篇关于子文档中的 SD MongoDB 多态性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆