#Value annotation for reading Map from property file - spring

My Java has this
#Value("#{${validators}}")
private Map<String,String> validators;
property file has this
validators={AlphabetValidator:'AlphabetValidator',NumberValidator:'NumberValidator'AlphaNumericValidator:'AlphaNumericValidator',DateValidator:'DateValidator', FixedLengthValidator:'FixedLengthValidator',MinimumLengthValidator:'MinimumLengthValidator',MaximumLengthValidator:'MaximumLengthValidator',CustomValidator:'CustomValidator' MandatoryFieldValidator: 'MandatoryFieldValidator',TimeValidator:'TimeValidator'}
when I run the app.. I am getting this error
Exception in thread "main"
org.springframework.beans.factory.UnsatisfiedDependencyException:
Error creating bean with name 'validatorProperties': Unsatisfied
dependency expressed through field 'validators'; nested exception is
org.springframework.beans.factory.BeanExpressionException: Expression
parsing failed; nested exception is
org.springframework.expression.spel.SpelParseException: EL1041E:(pos
1): After parsing a valid expression, there is still more data in the
expression: 'lcurly({)'

Check out for comma ',' in property file.
Properties file:
validators={AlphabetValidator:'AlphabetValidator',NumberValidator:'NumberValidator',AlphaNumericValidator:'AlphaNumericValidator',DateValidator:'DateValidator',FixedLengthValidator:'FixedLengthValidator',MinimumLengthValidator:'MinimumLengthValidator',MaximumLengthValidator:'MaximumLengthValidator',CustomValidator:'CustomValidator',MandatoryFieldValidator:'MandatoryFieldValidator',TimeValidator:'TimeValidator'}
Java code:
#Value("#{${validators}}")
private Map<String,String> validators;

You have missed to specify some commas inside your properties. Try with following:
validators={AlphabetValidator:'AlphabetValidator',NumberValidator:'NumberValidator',AlphaNumericValidator:'AlphaNumericValidator',DateValidator:'DateValidator',FixedLengthValidator:'FixedLengthValidator',MinimumLengthValidator:'MinimumLengthValidator',MaximumLengthValidator:'MaximumLengthValidator',CustomValidator:'CustomValidator',MandatoryFieldValidator:'MandatoryFieldValidator',TimeValidator:'TimeValidator'}

Related

Spring Data: Mongo Repository can not be initialized

I'm getting this strange error message when I start my spring boot service:
Caused by: org.springframework.data.mapping.PropertyReferenceException: No property storeMpi found for type Patient!
Service can't be started since this exception is raised.
My code is very straight:
public interface PatientRepository
extends MongoRepository<Patient, String>,
QuerydslPredicateExecutor<Patient>,
MPIPatientRepository
{
}
public interface MPIPatientRepository {
Patient storeMpi(Patient patient);
}
You can see, that storeMpi is a method, not an expected field of my Patient entity.
Implementation is straight as well:
#Repository
#RequiredArgsConstructor
public class MPIPatientRepository implements cat.gencat.catsalut.hes.mpi.repository.MPIPatientRepository {
private final MongoTemplate mongoTemplate;
/**
* {#inheritDoc}
*/
#Override
public Patient storeMpi(Patient patient) {
return this.mongoTemplate.save(patient);
}
I don't quite figure out what's wrong.
Formatted root CausedBy is:
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'ca.uhn.fhir.spring.boot.autoconfigure.FhirAutoConfiguration$FhirRestfulServerConfiguration': Bean instantiation via constructor failed;
nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [ca.uhn.fhir.spring.boot.autoconfigure.FhirAutoConfiguration$FhirRestfulServerConfiguration$$EnhancerBySpringCGLIB$$5fe4b535]: Constructor threw exception;
nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'patientResourceProvider' defined in file [/home/jeusdi/projects/salut/mpi/hes-mpi-fhir-mongodb/target/classes/cat/gencat/catsalut/hes/mpi/providers/PatientResourceProvider.class]: Unsatisfied dependency expressed through constructor parameter 0;
nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'patientService' defined in file [/home/jeusdi/projects/salut/mpi/hes-mpi-fhir-mongodb/target/classes/cat/gencat/catsalut/hes/mpi/service/PatientService.class]: Unsatisfied dependency expressed through constructor parameter 2;
nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'patientRepository' defined in cat.gencat.catsalut.hes.mpi.repository.PatientRepository defined in #EnableMongoRepositories declared on MongoRepositoriesRegistrar.EnableMongoRepositoriesConfiguration: Invocation of init method failed;
nested exception is org.springframework.data.repository.query.QueryCreationException: Could not create query for public abstract cat.gencat.catsalut.hes.mpi.model.Patient cat.gencat.catsalut.hes.mpi.repository.MPIPatientRepository.storeMpi(cat.gencat.catsalut.hes.mpi.model.Patient)! Reason: No property storeMpi found for type Patient!;
nested exception is org.springframework.data.mapping.PropertyReferenceException: No property storeMpi found for type Patient!
Any ideas?

Reading environment variables or properties in a file

I am trying to deploy a spring-boot 2.0.4 application. The configuration looks like below :
#Component
#Configuration
#PropertySource("classpath:elast.properties")
public class ElastSearchLogLevel {
private static final Logger LOG = LoggerFactory.getLogger(ElastSearchLogLevel.class);
#Value("${elast.mail.to}")
private String to;
...
Locally on windows its working fine but in Linux box it says :
WARN o.a.commons.logging.impl.Jdk14Logger.log - Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'elastSearchBootApplication': Unsatisfied dependency expressed through field 'logsSearch'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'elastSearchLogLevel': Injection of autowired dependencies failed; nested exception is java.lang.IllegalArgumentException: Could not resolve placeholder 'elast.mail.to' in value "${elast.mail.to}"
The instance 'elastSearchLogLevel' is autowired in SpringBootApplication class. Ideally i want to give an external configuration file from which the property can be read. As suggested in one of the forum I also tried but didn't work.
#PropertySource("classpath:file:///my/file/path/elast.properties")
ok some more code :
#ComponentScan(basePackages = "some.packer.log")
#SpringBootApplication
#EnableScheduling
public class ElastSearchBootApplication {
...

Parse LocalTime string inside the #Value attribute

My environment variable is a string with time 23:30 In my String Boot application I'd like to parse it automatically and set it the result to variable.
I tried like this
#Value("#{ java.time.LocalTime.parse('${NIGHT_START_TIME}')}")
private LocalTime NIGHT_START_TIME;
IntelliJ shows the error
Cannot resolve variable 'java'
Here is log
Unsatisfied dependency expressed through field 'NIGHT_START_TIME';
nested exception is org.springframework.beans.factory.BeanExpressionException: Expression parsing failed; nested exception is org.springframework.expression.spel.SpelEvaluationException: EL1008E: Property or field 'LocalTime' cannot be found on object of type 'org.springframework.beans.factory.config.BeanExpressionContext' - maybe not public?
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:588)
If I read variable like this I see that value is correct
#Value("${NIGHT_START_TIME}")
private String NIGHT_START_TIME;
Any ideas how to make it work?
Try this
#Value("#{ T(java.time.LocalTime).parse('${NIGHT_START_TIME}')}")
private LocalTime NIGHT_START_TIME;
The way you reference a class is using T.
Check the documentation.
Have checked at Spring Boot 2.2.6.RELEASE:
application.yml
NIGHT_START_TIME: '23:30'
Service
#Value("${NIGHT_START_TIME}")
private LocalTime NIGHT_START_TIME;
Work perfect without any "knee bends":)

Spring | SPEL multiple property accessors

I'm trying to use SPeL with multiple property accessors.
StandardEvaluationContext simpleContext = new StandardEvaluationContext(myPojo);
simpleContext.setVariable("ctx", ruleExecutionContext);
simpleContext.setPropertyAccessors(Arrays.asList(new MapAccessor(), new ReflectivePropertyAccessor()));
ExpressionParser parser = new SpelExpressionParser();
return (Boolean) parser.parseExpression(spelExpression).getValue(simpleContext, RulebaseConfiguration.LIB_MAP);
RulebaseConfiguration.LIB_MAP contains {"instanceName": instance}
I want to pass expressions that could operate on a POJO as well as call methods on the instance. But it only takes map into the effect.
I get this error:
SEVERE: Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.springframework.expression.spel.SpelEvaluationException: EL1008E: Property or field 'payload' cannot be found on object of type 'java.util.HashMap' - maybe not public?] with root cause
org.springframework.expression.spel.SpelEvaluationException: EL1008E: Property or field 'payload' cannot be found on object of type 'java.util.HashMap' - maybe not public?
at org.springframework.expression.spel.ast.PropertyOrFieldReference.readProperty(PropertyOrFieldReference.java:226)
Creating a context and parsing the expression for each request is wasteful, unless it's different for each request; in which case, consider caching expressions/contexts.
As I said, since you are passing a rootObject to getValue(), your myPojo is "hidden" - the evaluation is always performed on LIB_MAP.
You need to call getValue() without a root object to use the context's root object. You can add LIB_MAP as a variable (e.g. with name nationalityLookup) and use
payload['channel'] == #nationalityLookup.resolveChannel('CBR1000')

Inject date using #Value annotation

This is how I am trying to inject a date into a #Component class.
#Value("${new java.text.SimpleDateFormat(\"yyyyMMdd\").parse(\"${PROP_DATE}\")}")
Date myDate;
The date is specified as a String in properties file :
PROP_DATE=20110421
I get this error. What am I doing wrong? Is there any other way to inject Date property? Thanks.
Exception in thread "main" org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'ccc': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: java.util.Date aaa.bbb.ccc.myDate; nested exception is java.lang.IllegalArgumentException: Could not resolve placeholder 'new java.text.SimpleDateFormat("yyyyMMdd").parse("20110421")'
Use #{new java.text.SimpleDateFormat(\"yyyyMMdd\").parse(\"${PROP_DATE}\")} for process value with spEL

Resources