SpEL used in @Document indexName with spring data elasticsearch and spring boot is not being parsed
Asked Answered
T

1

10

looking for some help using the SpEL inside @Document annotation in reference to:

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

i am having trouble googling for help with this problem as the keywords pick up unrelated questions (i have seen the other (unanswered) question about dynamic indexName).

i would like to set the

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

with the value for the indexName derived from a property (es.index-name) value written in my application.properties.

it is instead using the literal String value "${es.index-name}" as the index name!

i have also tried creating a @Component called EsConfig

with a field indexName annotated with @Value("${es.index-name}")

and then trying to access this component property value using SpEL:

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

but this does not work either (still parsing as literal String and complains of uppercase). i have confirmed through the debugger that the EsConfig component IS parsing the SpEL correctly and providing the right value. but it fails when reaching @Document

here are the full code snippets:

using @Document with SpEL accessing application.properties

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 data source Component (tried with and without using 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;
  }
}

using @Document with SpEL accessing EsConfig indexName property

@Data
@Document(indexName = "#{esConfig.indexName}", type = "tests")
public class TestDocument {
  @Id
  @GeneratedValue(strategy = GenerationType.AUTO)
  private String id;
}
Tweeddale answered 11/12, 2019 at 2:46 Comment(0)
V
12

Reference your bean with the name and method:

@Document(indexName = "#{@esConfig.getIndexName()}")
Vigor answered 11/12, 2019 at 15:36 Comment(6)
my god thank you. this has been driving me insane for daysTweeddale
do you happen to know why neither "${es.index-name}" nor "#{esConfig.indexName}" worked?Tweeddale
the index name argument is parsed with a SpelExpressionParser that needs #{...}. and within that expression you need to reference the bean with @ and you need to use the getter methods, no direkt property access. You can try #{es.index-name} but I'm not sure if the parsers uses the environemtn or only the available beans.Vigor
i see. what confused me is that my friend was using spring boot 2.1.x + spring data elasticsearch 3.1.x and for him @Document(indexName = "#{esConfig.indexName}") did work. i could not figure out why just moving up the minor versions had such a drastic difference. and nothing in the change logs reflecting this. thank you again for your helpTweeddale
strange ideed, I am not aware of a change at that place. But glad I could help youVigor
I have spent months trying to set the index-name dynamically for different environments. Thanks for this solution!Coverley

© 2022 - 2024 — McMap. All rights reserved.