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
应该返回Superclass
和Subclass
对象.它在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)
这对我有用,我只是担心需要更长的时间