我正在将一个应用程序迁移到最新的spring-boot
版本(使用2.5.4版本的maven spring-boot-dependencies)。
我有一个名为Customer的接口,并且我有该接口的两个实现(BusinessCustomer
,PrivateCustomer
)
这三个类的注释如下:
@Document(indexName = "customers", type = "customer")
@JsonTypeInfo(
use = JsonTypeInfo.Id.NAME,
include = JsonTypeInfo.As.EXISTING_PROPERTY,
property = "customerType"
)
@JsonSubTypes({
@JsonSubTypes.Type(value = BusinessCustomer.class, name = "BUSINESS_CUSTOMER"),
@JsonSubTypes.Type(value = PrivateCustomer.class, name = "PRIVATE_CUSTOMER")
})
public interface Customer {
@JsonIgnoreProperties(ignoreUnknown = true)
@JsonTypeInfo(
use = JsonTypeInfo.Id.NAME,
include = JsonTypeInfo.As.EXISTING_PROPERTY,
property = "customerType",
defaultImpl = BusinessCustomer.class
)
@Entity
@Document(indexName = "customers", type = "customer")
public class BusinessCustomer implements Serializable, Customer, Cloneable {
@JsonIgnoreProperties(ignoreUnknown = true)
@JsonTypeInfo(
use = JsonTypeInfo.Id.NAME,
include = JsonTypeInfo.As.EXISTING_PROPERTY,
property = "customerType",
defaultImpl = PrivateCustomer.class
)
@Entity
@Document(indexName = "customers", type = "customer")
public class PrivateCustomer implements Serializable, Customer, Cloneable {
查询索引"客户";我曾经有这样的代码:
elasticsearchOperations.count(query, Customer.class);
但是这已经不起作用了。我在运行时得到一个错误:
Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.springframework.data.mapping.model.MappingInstantiationException: Failed to instantiate Customer using constructor NO_CONSTRUCTOR with arguments ] with root cause org.springframework.beans.BeanInstantiationException: Failed to instantiate [Customer]: Specified class is an interface
是不可能有两个不同的类在同一个索引像这样吗?现在是否要以某种方式使用ElasticsearchCustomConversions ?
Spring Data Elasticsearch中的MappingElasticsearchConverter
不能在接口上工作,而是依赖于在实体类上设置的@Document
和@Field
注释。
所有Spring Data模块——不仅仅是Spring Data Elasticsearch——都使用PersistentEntity
的概念,这是关于要存储的类的元信息。PersistentProperty
s,这是关于类属性的元信息。对于Spring Data Elasticsearch,这是关于Elasticsearch中字段名的信息,它是type,日期格式等信息
带@Document
注释的类与索引相关联。从版本7开始,Elasticsearch不再支持在一个索引中包含多个类型。
所以你应该把不同的实体存储在两个索引中:
@Document(indexName="business-customers")
class BusinessCustomer {
// ...
}
@Document(indexName="private-customers")
class PrivateCustomer {
// ...
}
在一次调用中搜索这两个索引并返回不同的数据是可能的,我写了一篇关于如何做到这一点的博客文章(https://www.sothawo.com/2021/05/reading-different-entities-from-multiple-indices-with-one-call-using-spring-data-elasticsearch/)。