Spring Data Mongodb存储库不能正确实现继承

Mat*_*ski 10 java spring spring-data spring-data-mongodb

有两种类型的实体,它们映射到单个MongoDB集合中的两个Java类:

@Document
public class Superclass { ... }

@Document(collection = "superclass")
public class Subclass extends Superclass { ... }
Run Code Online (Sandbox Code Playgroud)

和这些实体的两个存储库:

public interface SuperclassRepository extends MongoRepository<Superclass, String> {}
public interface SubclassRepository extends MongoRepository<Subclass, String> {}
Run Code Online (Sandbox Code Playgroud)

MongoRepositories不要正确处理实体的继承.在查询所有Subclass对象(例如SubclassRepository.findAll())时,结果集包含Superclass对象,这些对象是实例化的(或者至少已经尝试实例化),对于属于Subclass但不属于的一部分的字段具有空值Superclass.

预期的结果是SubclassRepository应该只返回Subclass对象,而SuperclassRepository应该返回SuperclassSubclass对象.它在Spring Data JPA中以这种方式工作.

有没有人遇到过这个bug并且有任何解决方法可以解决它?

小智 4

我遇到同样的问题。

看一下源代码,令我惊讶的是它没有实现。它添加集合名称和实体类,但不会在最终查询中插入 _class 属性。看完之后我意识到 Mongo 如何知道 SubClass1 或 Subclass2 是从 SuperClass 派生的。所以我只是重写 SimpleMongoRepository 类并创建自己的工厂来放置该类而不是默认的 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());
}
Run Code Online (Sandbox Code Playgroud)

这是一个 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());
}
Run Code Online (Sandbox Code Playgroud)

这对我有用,我只是担心需要更长的时间