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

时间:2015-01-19 13:26:42

标签: java spring spring-data spring-data-mongodb

有两种类型的实体,它们映射到单个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应返回SuperclassSubclass个对象。它在Spring Data JPA中以这种方式工作。

有没有人遇到过这个bug,并且有解决方法吗?

1 个答案:

答案 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());
}

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