使用Spring Data Elasticsearch和Spring Boot中的SpEL在@Document indexName中未被解析。

10

寻求使用SpEL在@Document注释中的帮助,与以下内容相关:

spring-data-elasticsearch:3.2.3.RELEASE 和 spring boot 2.2.1 RELEASE

我在谷歌上搜索此问题时遇到了困难,因为关键字会捕捉到无关的问题(我已经看到了其他(未回答)有关动态indexName的问题)。

我想设置

@Document(indexName = "${es.index-name}", ...)

使用在我的application.properties文件中编写的属性(es.index-name)值派生的indexName的值。

它实际上使用字面字符串值"${es.index-name}"作为索引名称!

我还尝试创建一个名为EsConfig@Component

其中包含一个indexName字段,该字段带有@Value("${es.index-name}")注释

然后尝试使用SpEL访问此组件属性值:

@Document(indexName = "#{esConfig.indexName}", ...)

但这也不起作用(仍将其解析为字面字符串并抱怨大写)。我已通过调试器确认EsConfig组件正确解析SpEL并提供正确的值。但在到达@Document时失败。

以下是完整的代码片段:

使用访问application.properties的SpEL和@Document

import lombok.Data;
import org.springframework.data.elasticsearch.annotations.Document;

import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;

@Data
@Document(indexName = "${es.index-name}", type = "tests")
public class TestDocument {
  @Id
  @GeneratedValue(strategy = GenerationType.AUTO)
  private String id;
}

EsConfig数据源组件(尝试使用和不使用Lombok)

import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

@Component("esConfig")
public class EsConfig {
  @Value("${es.index-name}")
  private String indexName;

  public String getIndexName() {
    return indexName;
  }

  public void setIndexName(String indexName) {
    this.indexName = indexName;
  }
}


使用SpEL访问EsConfig的indexName属性时,可以使用@Document注解。
@Data
@Document(indexName = "#{esConfig.indexName}", type = "tests")
public class TestDocument {
  @Id
  @GeneratedValue(strategy = GenerationType.AUTO)
  private String id;
}
1个回答

12

使用名称和方法引用您的bean:

@Document(indexName = "#{@esConfig.getIndexName()}")

1
我的天啊,谢谢你。这个问题已经让我疯了好几天了。 - vampiire
你知道为什么"${es.index-name}"和"#{esConfig.indexName}"都没起作用吗? - vampiire
索引名称参数使用需要 #{...} 的 SpelExpressionParser 进行解析。在该表达式中,您需要使用 @ 引用 bean,并且需要使用 getter 方法,而不是直接属性访问。您可以尝试使用 #{es.index-name},但我不确定解析器是否使用环境或仅使用可用的 bean。 - P.J.Meisch
我明白了。让我困惑的是,我的朋友正在使用Spring Boot 2.1.x + Spring Data Elasticsearch 3.1.x,而对他来说@Document(indexName = "#{esConfig.indexName}")是有效的。我无法弄清楚为什么只是将次要版本向上移动就会有如此巨大的差异,而且变更日志中也没有反映这一点。再次感谢您的帮助。 - vampiire
确实很奇怪,我不知道那个地方有什么变化。但很高兴我能帮到你。 - P.J.Meisch
1
我花了数月时间尝试为不同的环境动态设置索引名称。感谢这个解决方案! - Chris Webster

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接