Similar question has been asked and answered back in 2015 here .
However , rather than storing queries in XML files , I would like to store them in external .sql files and read query from there. To achieve this in our spring boot application - 2.1.5.RELEASE with Java 8 , we are storing queries in resources folder as below
src/main/resources - queries - A.sql - B.sql
To read the above queries , I'm reading them in QueryReader class as below
@Component
public class QueryReader {
public String getQueryFromFile(String fileName) {
System.out.println("getQueryFromFile() : " + fileName);
return this.convertInputStreamToString(this.getTemplateAsStream(fileName));
}
private InputStream getTemplateAsStream(String queryFileName){
ClassLoader classLoader = getClass().getClassLoader();
InputStream iStream =classLoader.getResourceAsStream("queries/" + queryFileName);
return iStream;
}
}
And to use it anywhere in the code , i'm having below class , so that i can call it's methods
@Component
public class MyQueries {
@Autowired
private QueryReader qfr;
public String queryErroredRecords() {
return qfr.getQueryFromFile("A.sql");
}
While using it with JDBCTemplate , this works as expected but when I'm trying to use this method from @Query annotation from Repository , i'm not able to do so with errors as below.
Repository Code
@Repository
public interface AdminRepository extends JpaRepository<OrderBackupRecordEO, BigDecimal>{
@Autowired
public MyQueries queries;
@Query(value = queries.queryErroredRecords() , nativeQuery= true)
List<String> findX();
}
Above repository is giving errors as below :
1.The value for annotation attribute Query.value must be a constant expression (For @Query annotation)
2.The blank final field queries may not have been initialized (For @Autowired annotation)
How can I make it work?
I would just add a note that may be helpful for you.
Your solution cannot work just because in java in an interface all the fields (variables) are by default public , static and final and that why you cannot @Autowire any dependencies inside the interface.
That's why it works for your case for JDBCTemplate (which is a class) and doesn't work for spring data repository (which is an interface).
Spring already has a solution "from the box", you don't need to make all these manipulations.
@Repository
public interface AdminRepository extends JpaRepository<OrderBackupRecordEO, BigDecimal> {
List<String> findX();
}
File src/main/resources/META-INF/jpa-named-queries.properties
:
OrderBackupRecordEO.findX=\
SELECT record FROM OrderBackupRecordEO record WHERE ...
That's all! No any loading, manipulations, manual handling - an implementation is hidden in Spring - very simple and reliable.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.