spring-boot-starter-data-mongodb don't include GridFSBucket bin as autoconfigured - spring

GridFSBucket is not auto configured in Spring boot parent in 2.1.3.REALEASE, so cant be autowired. But GridFsTemplate is autowire as it is autoconfigured. how to get gridFSBucket from gridFsTemplate. Actually i want to use 'downloadToStream' method to write to a file. If that is possible by GridFSFile then not required.

I had the same issue while migrating, trying to load a PDF stored in MongoDB, causing the file to be corrupted (startxref not found)
Following this answer helped me: https://stackoverflow.com/a/50732308/590374

GridFSFile file = gridFsTemplate.findOne(Query.query(Criteria.where("_id").is(fileId)));
GridFsResource resource = gridFsTemplate.getResource(file);
return resource.getInputStream();

Related

Spring Boot: Can't find File located in resources folder with #Value annotation

Simple problem (I think): I'm attempting to load files with the #Value annotation, but Spring Boot does not see a file there.
#Value("classpath:/*.xlsx")
private Resource[] inputResources;
I'm using inputResources as an input to a Spring Batch method, which then fetches all files matching my wildcard.
MultiResourceItemReader<Employee> resourceItemReader = new MultiResourceItemReader<Employee>();
resourceItemReader.setResources(inputResources);
The Excel spreadsheets are located in my resources folder. Any reason why this wouldn't work??
#Value Annotation is used in Spring to read a single value from a property file. It can not be used to read a whole file.
To read a file try something like this:
Resource resource = new ClassPathResource("classpath:data.txt");
InputStream inputStream = resource.getInputStream();
...
You could use #Value to have this String "classpath:data.txt" not hardcoded.

Externalizing configuration for Hibernate Search

I am running hibernate search with spring boot. I have written a working configuration for my application. How ever, i want to externalize my configuration and use ./config/hibernate.properties instead of src/main/resources/hibernate.properties. After copying my properties file to the desired location, i am getting and exception:
nested exception is java.io.FileNotFoundException: class path resource [hibernate.properties] cannot be opened because it does not exist
Anyone with any idea on how i should tell spring to read my configuration file?
Move your configuration to an src/main/resources/application.properties file and prepend spring.jpa.properties. everywhere, so hibernate.dialect will become spring.jpa.properties.hibernate.dialect, for example.
Then you can use Spring features to move your configuration wherever you want. To move it to ./config/application.properties I suppose you will have to add #PropertySource("./config/application.properties") to one of your #Configuration classes, or something similar.
I'm sure you can also keep the hibernate configuration in a separate file (separate from the rest of your application configuration).
See https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-external-config.html for more details about externalizing configuration in Spring Boot.
For some reason, it seems hibernate-search will prevent application from starting as long as a hibernate.properties configuration file does not exist. After trying for a while without success, i found a work around for my problem.
First, i created an empty hibernate.properties file and place it under src/main/resources.
Secondly, i moved all hibernate-search configurations to application.properties as follows:
spring.jpa.properties.hibernate.search.default.indexmanager = elasticsearch
spring.jpa.properties.hibernate.search.default.elasticsearch.host = http://my-server.com
spring.jpa.properties.hibernate.search.default.elasticsearch.index_schema_management_strategy = CREATE
spring.jpa.properties.hibernate.search.default.elasticsearch.required_index_status = yellow
This way, the application will start and spring will get all configuration from the externalized configuration as documented here.

How to Access Spring Configuration Outside a JAR File

I am new with Spring Boot Development and currently can't move-on on the issue of how to load my spring application configuration outside the jar file.
My existing code looks like this
private ApplicationContext context;
public static void main(String[] args){
SpringApplication.run(SMPPEngine.c1ass);
new SMPPEngine();
}
public SMPPEngine(){
loadConfiguration();
process();
}
private void loadConfiguration(){
context = new ClassPatthlApplicationContext(”application-context.xm1”);
}
What I want to achieve is to have the jar file next to application-context.xml in one directory so that when there are configuration changes,I don't need to recompile my code just to reflect the changes on application-context.xml.
Based on what I've read on the internet, this is possible by using 'file://directory/application.xml' instead of classpath. But my problem on using the later is that when you place your jar and file to other location, I am required to do code change to reflect the new directory which does not solve the problem of getting away from code recompilation.
I hope I made my issue clear, and get an immediately response with you guys :)
Thanks in advance :)
There are many approaches to do this, standard, you can use spring file: prefix for accessing filesystem paths.
but with spring boot, you can specifiy it in application.properties with
spring.config.location propertiy, or you can add it in command line when run the spring boot jar file like
java -jar myproject.jar --spring.config.location=classpath:/default.properties,classpath:/override.properties
But for your codes, actually you do not need to re-create the spring context from the configuration files, but you want get the context instance, you just need to inject it
#Autowired
private ApplicationContext context;
Another approach, if you have the infrastructure. Would be to use Spring Cloud Config. After your Boot application is configured to read from it, they can be modified at anytime without recompilation or restarting.

How to config #RetryTransaction in Spring?

I get this error :
Getting “Deadlock found when trying to get lock; try restarting transaction”
I'm trying to resolve it using annotation RetryTransaction with #Transactionnal.
But the annotation cannot be resolved to a type.
What is the config to set in spring-config.xml to make it work ? or maybe supplementary dependecies to install ?
Googling a bit reveals that the annotation you mentioned is not from spring, but someone else produced it.
You can get the maven artefact that contains it from here http://mvnrepository.com/artifact/org.dellroad/dellroad-stuff/1.0.659

Spring cannot load java based configuration

I want to create a Solr data import handler using Spring as the Ioc. When I try to invoke the handler from Solr, I got below error
Caused by: org.springframework.beans.factory.BeanDefinitionStoreException: Failed to load bean class: com.yoox.shanghai.AppConfig; nested exception is java.io.FileNotFoundException: class path resource **[com/my/app/AppConfig.class]** cannot be opened because it does not exist
Note the path printed in the message. It looks like it is using a relative path. I have no idea what is the cause.
I am using the Java based container configuration, and the compilation passes. And my code works with JUnit4.
appCtx = new AnnotationConfigApplicationContext(AppConfig.class);
Are you sure that you import AppConfig properly? Otherwise make sure that the class has really been deployed (check the deployment directory).
I googled for a long time, but could not find any answer about how spring resolve the class path by default. But I found people are trying to explicitly set the class loader, so I tried.
appCtx = new AnnotationConfigApplicationContext();
appCtx.setClassLoader(this.getClass().getClassLoader());
appCtx.register(AppConfig.class);
appCtx.refresh();
And it works :D
However I am not satisfied with this answer. I hope some one can point out what's wrong with my class loading logic.

Resources