Spring 数据弹性搜索:在 POJO 接口上使用 @Document 注释 class 不工作
Spring data elasticsearch: Using @Document annotation on POJO interface class not working
我正在将一个应用程序迁移到最新的 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 以某种方式完成此操作?
SpringData Elasticsearch中的MappingElasticsearchConverter
在接口上不起作用,而是依赖于在实体上设置的@Document
和@Field
注释class.
所有 Spring 数据模块 - 不仅是 Spring Data Elasticsearch - 使用 PersistentEntity
的概念,即关于要存储的 class 的元信息。而 PersistentProperty
s,这是关于 class 属性的元信息。对于 Spring Data Elasticsearch,这是有关 Elasticsearch 中字段名称的信息,它是类型,
日期格式等信息
一个 @Document
注释 class 与一个索引相关联。由于版本 7 Elasticsearch 不再支持在一个索引中包含多种类型。
因此您应该将不同的实体存储在两个索引中:
@Document(indexName="business-customers")
class BusinessCustomer {
// ...
}
@Document(indexName="private-customers")
class PrivateCustomer {
// ...
}
在一个调用中搜索这两个索引并返回不同的数据是可能的,我写了一篇博客 post 关于如何做到这一点 (https://www.sothawo.com/2021/05/reading-different-entities-from-multiple-indices-with-one-call-using-spring-data-elasticsearch/)。
我正在将一个应用程序迁移到最新的 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 以某种方式完成此操作?
SpringData Elasticsearch中的MappingElasticsearchConverter
在接口上不起作用,而是依赖于在实体上设置的@Document
和@Field
注释class.
所有 Spring 数据模块 - 不仅是 Spring Data Elasticsearch - 使用 PersistentEntity
的概念,即关于要存储的 class 的元信息。而 PersistentProperty
s,这是关于 class 属性的元信息。对于 Spring Data Elasticsearch,这是有关 Elasticsearch 中字段名称的信息,它是类型,
日期格式等信息
一个 @Document
注释 class 与一个索引相关联。由于版本 7 Elasticsearch 不再支持在一个索引中包含多种类型。
因此您应该将不同的实体存储在两个索引中:
@Document(indexName="business-customers")
class BusinessCustomer {
// ...
}
@Document(indexName="private-customers")
class PrivateCustomer {
// ...
}
在一个调用中搜索这两个索引并返回不同的数据是可能的,我写了一篇博客 post 关于如何做到这一点 (https://www.sothawo.com/2021/05/reading-different-entities-from-multiple-indices-with-one-call-using-spring-data-elasticsearch/)。