2

I wanted to externalize the configuration for @EnableJPARepositories basePackages.

I have two different sample packages below

  • com.project.ph.dao
  • sample.project.jpa.repositories

I tried property externalization below (not working for multiple packages)

ProjectConfig.class

@EnableJpaRepositories(basePackages = {"${basePackages}"})

config.properties

basePackages=com.project.ph.dao,sample.project.jpa.repositories

Is there any other way to externalize this configuration for multiple packages?

Thanks!

charmae
  • 1,080
  • 14
  • 38
  • No there isn't. attributes of an annotation have static values and do you really want to control that from the outside, it basically means you have lost control over what is bootstrapped in your application. – M. Deinum May 15 '18 at 17:54
  • You cannot use property placeholders inside @EnableJpaRepositories annotation attributes **to get a few packages instead one string with property placeholder**, but you can craft your own '@EnableJpaRepositoriesWithProperties` annotation where it will work, see the following answer: https://stackoverflow.com/questions/47635650/spring-data-jpa-how-to-programmatically-set-jparepository-base-packages/51629110#51629110 – Roman Puchkovskiy May 18 '19 at 15:36

1 Answers1

5

No, you can't use SPEL inside the @EnableJpaRepositories annotation. Reason being that the annotation might exist on a configuration bean with additional property sources defined that could override the properties used in the annotation, so you'd have a chicken and egg scenario trying to load the beans. But you can still solve your problem using Spring's configuration mechanisms.

With Spring Boot

Instead of declaring all of the packages in a single class, create two or more @Configuration beans that are enabled based on properties using the @ConditionalOnProperty annotation from Spring Boot, e.g.:

@Configuration
@EnableJpaRepositories(basePackages = "com.project.ph.dao")
@ConditionalOnProperty("com.project.ph.dao.enabled")
public class PhProjectRepostoriesConfiguration {
}

And then another:

@Configuration
@EnableJpaRepositories(basePackages = "sample.project.jpa.repositories")
@ConditionalOnProperty("sample.project.jpa.repositories.enabled")
public class SampleProjectRepostoriesConfiguration {
}

Then in your application.properties file:

sample.project.jpa.repositories.enabled=true
com.project.ph.dao.enabled=false

Without Spring Boot

This is similar, except instead of using @ConditionalOnProperty, you'll just use @Conditional. This requires you to implement a Condition class that will check the properties instead.

Additional Notes

When using the @EnableJpaRepositories annotation, the default basePackages will be the package of the annotated class, so you could also drop these @Configuration beans into the com.project.ph.dao and sample.project.jpa.repositories packages and remove the basePackages declaration from the annotation. You'll still need the rest of the annotations, but it's one less hard-coded value to manage.

References

Brian
  • 17,079
  • 6
  • 43
  • 66
  • You cannot use property placeholders inside @EnableJpaRepositories annotation attributes **to get a few packages instead one string with property placeholder**, but you can craft your own '@EnableJpaRepositoriesWithProperties` annotation where it will work, see the following answer: https://stackoverflow.com/questions/47635650/spring-data-jpa-how-to-programmatically-set-jparepository-base-packages/51629110#51629110 – Roman Puchkovskiy May 18 '19 at 15:36