Spring Data MongoDB - Views,@ CompoundIndex和注释继承

问题描述 投票:-1回答:2

我遇到了一个问题,试图将继承与MongoDB视图和@CompoundIndex结合使用。说我有一个集合items和该集合的视图称为itemsView。我在我的模型中代表这些实体,如下所示:

@Document(collection = "items")
@CompoundIndex(name = "view_active_available" def = "{active: 1, quantity: 1}")
public class Item {
    // Adding index on collection that view definition will leverage
}

然后,对于视图,我想扩展Item类,以便在从视图中读取时可以利用其成员,getter / setter等,如下所示:

@Document(collection = "itemsView")
public class ItemAvailable extends Item {
     // Now I can read from the view but treat them as `Item` instances
}

知道在视图上创建索引是不可能的,我检查了Spring Data MongoDB源代码以获取@CompoundIndex注释,并发现:

/**
 * Mark a class to use compound indexes.
 * ...
 */
@Target({ ElementType.TYPE })
@Documented
@Retention(RetentionPolicy.RUNTIME)
public @interface CompoundIndex {
    ...
}

完美,@CompoundIndex不是@Inherited所以这应该工作正常,我想。所以我构建并启动了我的应用程序,遗憾地遇到了这个问题:

org.springframework.beans.factory.BeanCreationException:创建名为'itemsView'的bean时出错:init方法的调用失败;嵌套异常是org.springframework.data.mongodb.UncategorizedMongoDbException:命令失败,错误166:'无法在视图上创建索引'

所以,Spring毕竟试图在视图上创建索引。

我正在努力实现的目标似乎是在处理视图(以及它们的实体,它们毕竟只是一个“普通的”非视图实体)时必然是一个常见的设计挑战。

为什么非继承的@CompoundIndex注释应用于子类?


更新:经过大量调试后,我相信这可能是Spring Data MongoDB中的一个错误。 MongoPersistentEntintyIndexResolver有一个potentiallyCreateCompoundIndexDefinitions方法,明确检查所讨论的类(实体)上是否存在@CompoundIndexes@CompoundIndex。它是通过调用Spring Data的BasicPersistentEntity.findAnnotation方法实现的。该方法遍历继承链,查找指定的注释,如果找到它,则返回它,无论它在类层次结构中的位置如何。在potentiallyCreateCompoundIndexDefinitions(或其他任何地方)没有检查是否在超类上找到了注释,如果是,那么是否存在@Inherited注释。

spring inheritance view annotations spring-data-mongodb
2个回答
0
投票

Spring Framework在查找注释时使用自己的逻辑,默认情况下会检查已实现的接口和超类类型。 @Inherited没有任何改变。

无论如何,正如我记得当我遇到类似的问题时,没有办法避免继承复合索引。


0
投票

Spring Data MongoDB的MongoPersistentEntityIndexResolver调用内部私有方法potentiallyCreateCompoundIndexDefinitions,传递它正在检查的BasicPersistentEntity。该方法反过来调用实体的findAnnotation方法,最终推迟到AnnotatedElementUtils.findMergedAnnotation

从该课程的文档:

支持@Inherited

获取语​​义后的方法将遵循Java的@Inherited注释的约定,除了本地声明的注释(包括自定义组合注释)将优先于继承注释。相反,查找语义之后的方法将完全忽略@Inherited的存在,因为查找搜索算法手动遍历类型和方法层次结构,从而隐式支持注释继承而不需要@Inherited。

因此,根据此文档,我遇到的行为是正确的。但是我相信这是Spring Data MongoDB的一个错误 - 要正确地尊重@Inherited,它需要调用get注释方法之一而不是find方法,以防止继承非@Inherited注释。

© www.soinside.com 2019 - 2024. All rights reserved.