我正在为 MongoDB 使用 Spring-Data:
版本信息——org.mongodb.mongo-java-driver 2.10.1版本,org.springframework.data.spring-data-mongodb 1.2.1.RELEASE。
我有一个与此处定义的案例类似的案例,即(抱歉格式化...):
我刚开始使用 spring-data-mongodb 用 Java 开发一些应用程序,遇到了一些我无法解决的问题:
我有几个这样的文档 bean:
@Document(collection="myBeanBar")
public class BarImpl implements Bar {
String id;
Foo foo;
// More fields and methods ...
}
@Document
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)
给出的解决方案是在抽象类上使用 @TypeAlias 注释,它告诉框架使用特定的实现(在本例中为 FooImpl)。
就我而言,我有接口成员,而不是抽象成员:
@Document(collection="myBeanBar")
public class BarImpl implements Bar {
String id;
IFoo foo;
// More fields and methods ...
}
我很不情愿在接口IFoo上放一个会给出默认实现的注解,相反我想告诉框架在实现BarImpl类的上下文中这个字段的默认实现是什么,类似于@JsonTypeInfo:
@Document(collection="myBeanBar")
public class BarImpl implements Bar {
String id;
@JsonTypeInfo(use = Id.CLASS, defaultImpl = FooImpl.class)
IFoo foo;
// More fields and methods ...
}
我找到了这个答案,它或多或少地说是为了避免使用接口。但我很高兴知道是否有更好的选择。
有任何想法吗?
谢谢!