10

Is it possible to specify dynamically (at runtime) the indexName for each @Document, for example, via a configuration file? Or is it possible to make @Document Spring environment (dev, prod) dependant?

Thank you!

4
  • Also need some environment / profile based solution. Index name hardwired into annotation is not best option ... Commented Oct 13, 2015 at 7:09
  • I was trying to do the same using something similar to when you use @Value, but no luck yet. See this question for more info. Commented Oct 15, 2015 at 7:18
  • You cant use @Value in this way because its not a bean managed/created by Spring but by you using new MyBean() . I still cant get idea behind this annotation settings. Everybody must deal with this for example when using diffent indexName for dev and prod. How do you do this? Commented Oct 15, 2015 at 18:05
  • @DavidMarko, at this point I am wondering if anybody reached production with spring-data-elasticsearch... Does anyone know an example? Commented Oct 19, 2015 at 18:53

4 Answers 4

28

The @Document annotation does not permit to pass the indexname in parameter directly. However I found a work around.

In my configuration class I created a Bean returning a string. In this string I injected the name of the index with @Value :

@Value("${etrali.indexname}")
private String indexName;

@Bean
public String indexName(){
    return indexName;
}

Afterward it is possible to inject the index into the @Documentation annotation like this :

@Document(indexName="#{@indexName}",type = "syslog_watcher")

It works for me, I hope it will help you.

Best regards

Sign up to request clarification or add additional context in comments.

2 Comments

Thanks, in fact, it's the SpEL solution
Where did you register you Bean? I did so in the @Configuration annotated ElasticsearchConfig class. Apparently I still get an java.lang.NoClassDefFoundError. Any suggestions?
4

The solution from Bruno probably works but the "I created a Bean returning a string" part is a bit confusing.

Here is how I do it :

  • Have the "index.name" key valued in an application.properties file loaded by "<context:property-placeholder location="classpath:application.properties" />"

  • Create a bean named ConfigBean annotated with @Named or @Component


    @Named
    public class ConfigBean {

      @Value("${index.name}")
      private String indexName;

      public String getIndexName() {
        return indexName;
      }

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

    }
  • Inject the value of configBean.getIndexName() into the "@Document" annotation using Spring EL : @Document(indexName = "#{ configBean.indexName }", type = "myType")

P.S. : You may achieve the same result directly using the implicit bean "systemProperties" (something like #{ systemProperties['index.name'] }) but it didn't work for me and it's pretty hard to debug since u can't resolve systemProperties in a programmatic context (https://jira.spring.io/browse/SPR-6651)

2 Comments

I do not know how made this work, but "@Named" cannot be applied on Classes, and "@Configuration" did not make the indexName discoverable
Well, maybe your "@Named" can't, but my javax.inject.Named can.
2

The Bruno's solution works but there is no need to create a new Bean in this way. What I do is:

  • create a bean annotated with @org.springframework.stereotype.Service where the index name is loaded from the database:
@Service
public class ElasticsearchIndexConfigService {

    private String elasticsearchIndexName;

    // some code to update the elasticsearchIndexName variable

    public String getIndexName() {
        return elasticsearchIndexName;
    }
}
  • call the getIndexName() method from the bean in the @Document annotation using the SpEL:
@Document(indexName = "#{@elasticsearchIndexConfigService.getIndexName()}", createIndex = false)
public class MyEntity {

}

The crucial part is to use @ - #{elasticsearchIndexConfigService.getIndexName()} won't work. I lost some time to figure this out.

Comments

2

This Worked for me
application.properties

index.prefix=test

then use this code

@Document(indexName = "#{@environment.getProperty('index.prefix')}")

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.