有两种类型的实体,它们映射到单个MongoDB集合中的两个Java类:
@Document
public class Superclass { ... }
@Document(collection = "superclass")
public class Subclass extends Superclass { ... }
和这些实体的两个存储库:
public interface SuperclassRepository extends MongoRepository<Superclass, String> {}
public interface SubclassRepository extends MongoRepository<Subclass, String> {}
MongoRepositories
无法正确处理实体的继承。在查询所有Subclass
个对象(例如SubclassRepository.findAll()
)时,结果集包含Superclass
个对象,这些对象被实例化(或者至少已经尝试实例化),其中的字段为空值Subclass
的一部分,但不属于Superclass
。
预期结果是SubclassRepository
应仅返回Subclass
个对象,而SuperclassRepository
应返回Superclass
和Subclass
个对象。它在Spring Data JPA中以这种方式工作。
有没有人遇到过这个bug,并且有解决方法吗?
答案 0 :(得分:3)
我遇到了同样的问题。
看看源代码,令我惊讶的是它有点没有实现。它添加了Collection名称和实体类,但未在最终查询中插入_class属性。 在看了之后我意识到Mongo将如何知道从SuperClass派生的SubClass1或Subclass2。 所以我只是覆盖SimpleMongoRepository类并创建我自己的Factory,它放置该类而不是默认的SimpleMongoRepository
我在这里添加了:
public MySimpleMongoRepository(MongoEntityInformation<T, ID> metadata, MongoOperations mongoOperations) {
Assert.notNull(mongoOperations);
Assert.notNull(metadata);
this.entityInformation = metadata;
this.mongoOperations = mongoOperations;
Reflections reflections = new Reflections("com.cre8techlabs.entity");
Set<String> subTypes = reflections.getSubTypesOf(entityInformation.getJavaType()).stream().map(Class::getName).collect(Collectors.toSet());
subTypes.add(entityInformation.getJavaType().getName());
this.baseClassQuery = Criteria.where("_class").in(subTypes.toArray());
}
这里是一个实现find
的例子public T findOne(ID id) {
Assert.notNull(id, "The given id must not be null!");
Query q = getIdQuery(id).addCriteria(baseClassQuery);
return mongoOperations.findOne(q, entityInformation.getJavaType(), entityInformation.getCollectionName());
}
它对我有用,我只是担心需要更长的时间