I have a table where the date field is a varchar. Since it is a legacy application I do not want to change the datatype. I want to write the following query in criteria. Any help will be highly appreciated
select * from ucms_vu vu where vu.case_e_dt is not null and to_date(vu.case_e_dt,'YYYY-MM-DD') = to_date('2018-02-02','YYYY-MM-DD')
Using purely JPA, I believe that is not possible. Because you are wanting to do a specific manipulation in a not manipulable data.
If you use Hibernate too, #Formula annotation resolves your problem.
You can create a attribute in your ucms_vu entity:
#Formula("to_date(case_e_dt,'YYYY-MM-DD')")
private Date caseE;
And your criteria would use this attribute to perform the query.
For Example:
Criteria criteria = session.createCriteria(Ucms_vu.class, "ucms");
criteria.add(Restrictions.eq("ucms.caseE", new Date("your date 02/02/2018"));
criteria.list();
Related
This question already has answers here:
How to replace table name with parameter value while using Spring Data JPA nativeQuery
(5 answers)
Closed 3 years ago.
I am using Hibernate and Spring data JPA to build a web project.
In Eclipse-Link we can use native query like
String tableName = "sometablename";
String query = "SELECT * FROM " +tableName +"WHERE id > 10";
In Hibernate I am using #Query annotation
#Query(value = "SELECT COUNT(r.id) as resultsCount FROM #{#resultTable} r WHERE r.customerId= :customerId AND r.is_deleted=0 AND r.is_ignored=0 ", nativeQuery = true)
Integer getResultsCount(#Param("customerId") int customerId,
#Param("resultTable") String resultTable);
I tried #{#resultTable} but this is getting replaced as a string with quote and i am getting an exception that
You have a error in your SQL Syntax
I want to use table name dynamically from params. Is it possible? And if yes, Please tell me how?
It's not possible, #org.springframework.data.jpa.repository.Query takes only jpql, you cannot pass the name of the table since it's not recognized as any entity.
It states the javadoc of Query:
/**
* Defines the JPA query to be executed when the annotated method is called.
*/
String value() default "";
The best solution would be not to pass tablename as string, but resolve it using for example inheritance (link) or rebuild your datamodel somehow. As a quick and dirty solution I would suggest creating a custom repository and using EntityManager.createNativeQuery and pass the sql there. But remember to validate the query you're composing (validate user input, use enums for table names), because it can lead to sql injection.
Your own observations actually answer your question:
I tried #{#resultTable} but this is getting replaced as a string with quote and i am getting an exception
The placeholders which are used inside the #Query query string are intended to filled with literal values. Hence, the table name ended up appearing as literal string, inside single quotes. This means that behind the scenes #Query and Spring are probably using a JDBC prepared statement. It is not possible to bind the name of the table. Allowing this would be a major security hole.
The only possible workaround here would be to concatenate your query string together, and then trying to use that string with #Query. But note that this would not be a safe option.
What you are doing is wrong, you are mixing business logic into DAO layer, i suggest you create two DAO's, each one with its own table and query, then into the business/service layer call the desired one.
How I can handle a field in PostgreSQL whit datatype 'jsonb'.
I want to map it to an entity and use it whit a JPQL Query (check if a field exists with the given ID)
It should be performant as possible.
I have a data JPA entity where it contains a "price" type Double. Now, the users need to able to filter the records based on that field (Between min and max). Now the problem is, the value in the DB can be null for some records. My data JPA repository uses a native query like "price BETWEEN :priceFrom AND :priceTo". Now, if the user does not specify anything in the filter conditions, all record including the ones where prices is null should be returned. However, this query does not return those record. I know, I can create a new method with query "price IS NULL" and check the filter values in my service layer and call the null version if nothing is specified. But, I have multiple fields with the same requirement then it results in a lot of duplicate methods to maintain. Is there a better approach to handle that situation?
It seems to me, that you can specify
(:priceFrom is null and :priceTo is null and price is null)
OR price between :priceFrom and :priceTo
if priceFrom and priceTo are entered, second part of OR will be used, otherwise it selects records where price is null
Since you are using Spring Data JPA - Specifications should solve this for you. This is a JPA Criteria based solution.
For any complex-enough API – searching/filtering your resources by very simple fields is simply not enough. A query language is more flexible and allows you to filter down to exactly the resources you need. Hence you should easily be able to program for NULL (in the scenario that you currently need) and anything else that you might need.
This is scalable for multiple fields and easy to code/configure. There are a few links which will give you more insight into it
Spring Blog
Tutorial 1
Tutorial 2
Hopefully, this is helpful.
Need help with Spring JPA. Say I want to find who checkout the car when gotten a traffic ticket. So that licenseNum and
citationDate is greater than checkoutDate and citationDate is less than returnDate; or
citationDate is greater than checkoutDate and returnDate is null.
Currently,
List<SomeEntity> findByLicenseNumAndCheckOutDatetimeBeforeAndReturnDatetimeAfterOrReturnDatetimeIsNullOrderByIdDesc()
produces #1 correctly but produces all licenseNum with returnDate null.
How do I write spring JPA statement with 'or' statement correctly?
You can actually think of using a Query annotation where you can specify a custom query. Yon can choose a more meaningful method name and easy to maintain/change.
I am working with a legacy system which requires doing a query for a partial match on a number field. So I want to do something like
where ID like concat(:num, '%') where num parameter is of the type Long. Is there a way to do that using Spring Data JPA derived queries. If the id was a string then I can simply do
findByIdContaining(String id)
I would appreciate any help.
No, this is not possible with derived queries (those where the query is derived from the method name). But it's easy with an annotated #Query annotation.