Error in spring mongodb for indexing a hashmap - spring

I created in a pojo a index as it follows for the properties "attributes" that is a Map class
#CompoundIndex(name = "attributes", def = "{'attributes.key' : 1,attributes.value:1}")
i wish index the keys and the values of that map . I read in a another stackoverflow that is possibile to create a index in a nested properties but i have this error
" Failed to instantiate [org.springframework.data.mongodb.core.MongoTemplate]: Factory method 'mongoTemplate' threw exception; nested exception is org.bson.json.JsonParseException: Invalid JSON input. Position: 25. Character: '.'."

Related

Invocation of init method failed; nested exception is java.lang.IllegalArgumentException: Validation failed for query

I'm new in java and spring, I need to make a query to two tables with a 1 to N pacient->event relationship.
Repository:
public interface EventJpaRepository extends JpaRepository<Events2, Long> {
#Query("select a.start,a.end, CONCAT(p.a_pat ,' ', p.a_mat ,' ',p.nombre) as title from events2,paciente p where e.rut_num=p.rut_num")
List<Events2> getAllEvents();
}
I got this error:
Error creating bean with name 'eventJpaRepository':
Invocation of init method failed; nested exception is java.lang.IllegalArgumentException: Validation failed for query for method public abstract java.util.List com.calendar.repository.EventJpaRepository.getAllEvents()!

#Value annotation for reading Map from property file

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'}

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')

Spring Batch Job for truncate table

I have a two step in my Job
Step 1-->Truncate data from table A
Step 2--> Read from different datasource and insert data into table A
In Step 1 initialization of writer bean is throwing the exception, below is the code of writer bean and exception.
#Bean
public ItemWriter truncateData() {
JdbcBatchItemWriter writer = new JdbcBatchItemWriter();
writer.setSql("TRUNCATE TABLE A");
writer.setDataSource(dwhDataSource);
return writer;
}
Exception:-
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'truncateData' defined in class path resource Invocation of init method failed; nested exception is java.lang.IllegalArgumentException: Using SQL statement with '?' placeholders requires an ItemPreparedStatementSetter
Please let me know if you need more information and i'm doing any wrong in creating the bean.

How to autowire mongoTemplate into custom type converter?

I'm trying to create a converter that will fetch object from DB by it's ObjectId. But the mongoTemplate is always empty in converter:
org.springframework.core.convert.ConversionFailedException:
Failed to
convert from type org.bson.types.ObjectId to type
com.atlas.mymodule.datadomain.MyObject for value
'130000000000000000000013';
nested exception is
java.lang.NullPointerException
Code:
#Component
public class ObjectIdToMyObjectConverter implements Converter<ObjectId, MyObject> {
#Autowired
private MongoTemplate mongoTemplate; // null ???
public MyObject convert(ObjectId objectId) {
return mongoTemplate.findById(objectId, MyObject.class); // <- NullPointerException
}
}
Configuration:
#Configuration
#ComponentScan
#EnableMongoRepositories
public abstract class MyModuleConfiguration extends AbstractMongoConfiguration {
#Override
public MongoClient mongo() throws Exception {
List<MongoCredential> mongoCredential = getMongoCredentials();
return mongoCredential == null ?
new MongoClient(getMongoServerAddresses()) :
new MongoClient(getMongoServerAddresses(), mongoCredential, getMongoClientOptions());
}
protected abstract List<MongoCredential> getMongoCredentials();
protected abstract MongoClientOptions getMongoClientOptions();
protected abstract List<ServerAddress> getMongoServerAddresses() throws UnknownHostException;
#Bean
public ObjectIdToMyObjectConverter objectIdToMyObjectConverter() {
return new ObjectIdToMyObjectConverter());
}
#Override
public CustomConversions customConversions() {
List<Converter<?, ?>> converters = new ArrayList<Converter<?, ?>>();
converters.add(objectIdToMyObjectConverter());
return new CustomConversions(converters);
}
}
Test Configuration:
public class MyModuleTestConfiguration extends MyModuleConfiguration {
// overrides abstract methods, defines connection details...
}
update:
I've updated the code according to #mavarazy suggestion (added ObjectIdToMyObjectConverter bean definition) but got an exception:
Error creating bean with name 'mongoTemplate': Requested bean is
currently in creation: Is there an unresolvable circular reference?
Full exception:
Error creating bean with name 'mongoTemplate' defined in com.atlas.MyModule.MyModuleTestConfiguration:
Bean instantiation via factory method failed;
nested exception is org.springframework.beans.BeanInstantiationException:
Failed to instantiate [org.springframework.data.mongodb.core.MongoTemplate]: Factory method 'mongoTemplate' threw exception;
nested exception is org.springframework.beans.factory.BeanCreationException:
Error creating bean with name 'mappingMongoConverter' defined in com.atlas.MyModule.MyModuleTestConfiguration: Bean instantiation via factory method failed;
nested exception is org.springframework.beans.BeanInstantiationException:
Failed to instantiate [org.springframework.data.mongodb.core.convert.MappingMongoConverter]: Factory method 'mappingMongoConverter' threw exception;
nested exception is org.springframework.beans.factory.BeanCreationException:
Error creating bean with name 'mongoMappingContext' defined in com.atlas.MyModule.MyModuleTestConfiguration: Bean instantiation via factory method failed;
nested exception is org.springframework.beans.BeanInstantiationException:
Failed to instantiate [org.springframework.data.mongodb.core.mapping.MongoMappingContext]: Factory method 'mongoMappingContext' threw exception;
nested exception is org.springframework.beans.factory.BeanCreationException:
Error creating bean with name 'customConversions' defined in com.atlas.MyModule.MyModuleTestConfiguration: Bean instantiation via factory method failed;
nested exception is org.springframework.beans.BeanInstantiationException:
Failed to instantiate [org.springframework.data.mongodb.core.convert.CustomConversions]: Factory method 'customConversions' threw exception;
nested exception is org.springframework.beans.factory.BeanCreationException:
Error creating bean with name 'objectIdToMyObjectConverter': Injection of autowired dependencies failed;
nested exception is org.springframework.beans.factory.BeanCreationException:
Could not autowire field: private org.springframework.data.mongodb.core.MongoTemplate com.atlas.MyModule.ObjectIdToMyObjectConverter.mongoTemplate;
nested exception is org.springframework.beans.factory.BeanCurrentlyInCreationException:
Error creating bean with name 'mongoTemplate': Requested bean is currently in creation: Is there an unresolvable circular reference?
Thanks.
ObjectIdToMyObjectConverter is not a spring bean. If you want #Autowired to work, create ObjectIdToMyObjectConverter as Spring bean, like this:
#Bean
public ObjectIdToMyObjectConverter objectIdToMyObjectConverter() {
return new ObjectIdToMyObjectConverter());
}
and #Autowire it in your configuration.
Following #Savash update
I have not paid enough attention to your configurations.
What you see is happening because you are trying to create MongoTemplate, which depends on CustomConversions, and at the same time CustomConversions depend on MongoTemplate, spring can't and should not do that.
As a solution:
You can create your CustomConversions with ApplicationContextAware, and extract MongoTemplate reference lazily on a first call.
I thought you are using CustomConversions as part of spring-integration or something. If so it does not need to be part of converters for Mongo. If you need it as MongoConverters, you are doing something really strange.
What is exact use case, you need this for?
Following comments:
Do I understand right, that you want MongoTemplate to read object with user reference as User object, and write object with User value as user reference?
I think.
You have a bad data model (you are trying to emulate JOIN operation in your MongoTemplate, which means you are missing something in your data model, and this is not how you should work with mongo).
Just call User explicitly when you need it, don't overload your DB with additional work, you'll have problems with performance
You can use another object, which you'll enrich with current user, as needed
Maybe SQL & ORM like Hibernate is a better approach for you ?
Try Hibernate OGM for your purpose, it might provide functionality, you need (Not sure, though, have not worked with it)

Resources