mysql use case in jpa query - mysql

I am building an endpoint where 3 query param comes in request like
status(mendatory)
searchCriteria(optional)
startDate(optional)
I am considering that i have to write three(3) native sql queries with combination of ex.
1: status and searchCriteria
2: status and startDate
3: status and searchCriteria and startDate
but I do not want to write three queries,
I know it is possible to achieve in a single query using case .
This is my native sql query
#Query(value = "select * from email_info u where u.status =:status and u.campaign =:searchCriteria and u.scheduleat =:startDate",
nativeQuery = true)
object getPromotional(String status, String searchCriteria, String startDate);
How to use case in above query using jpa like
CASE
WHEN :searchCriteria != null THEN u.campaign =:searchCriteria
WHEN :startDate != null THEN u.scheduleat =:startDate
END

Related

Nested query with Hibernate HQL

Please I want to include a nested select from in a hql query like this:
Query query1 = session.createQuery("from Component where ( AC_ID IS NULL) AND ( WIP_ID IS NOT NULL ) AND ( SELECT USER_ID FROM WorkInProcess WHERE WIP_ID = 'WIP_ID' IS NULL) ");
How could I achieve this with hibernate hql query.
Thank you
With minimal information given i would say there are two classes Component.class and WorkInProcess.class. I guess WIP_ID is foreign key for WorkInProcess.class. You can use the following hql query or detached criteria based query to achieve it:
session.createQuery("from Component m where m.AC_ID is NULL and WIP_ID IS NOT NULL and m.USER_ID IN (" +
"select e.USER_ID from WorkInProcess e where e.WIP_ID:=wip_id) is null").setParameter("wip_id", wip_id).uniqueResult();
or
DetachedCriteria Query1 = DetachedCriteria.forClass(WorkInProcess.class);
Query1.add(Restrictions.eq("WIP_ID", WIP_ID));
Criteria Query2 = session.createCriteria(Component.class);
Query2.add(Restrictions.isNull("AC_ID"));
Query2.add(Restrictions.isNotNull("WIP_ID"));
Query2.add(Property.forName("USER_ID").eq(Query1));
Please refer : hql-and-nested-queries

How to write a native SQL query in Grails 2.4.0?

I am working on Grails 2.4.0. I want to execute the native query in Groovy Controller. The query is as follow:
SELECT AVG(REPLACE(n.ep_text, 'PPM', '')), MONTH(n.date_creat)
from notification n
where n.type = 42
GROUP BY MONTH(n.date_creat)
Firstly, I execute the above query but it's have not found the REPLACE function like:
String query1 = "SELECT n.id, avg(REPLACE(n.epText, 'PPM', '')) FROM Notification as n";
def result = Notification.executeQuery(query1.toString())
How can I able to execute the REPLACE function in it?
And secondly, I have some R&D on it, but to execute the native query to required the sessionFactory. Unable to understand how to get the current session of Hibernate in Grails 2.4.0 to execute the native query?
Any help would be appreciated.
In order to use a native query, we can use SessionFactory, which is a bean and we can simply declare it to our Grails controller or service and dependency injection will handle it. Here is sample code using this bean to execute a native query.
class PublicService {
def sessionFactory
def getMatchedValue(){
def currentSession = sessionFactory.currentSession
def q = "select bank.id as id, bank.credit_amount as creditAmount, bank.debit_amount as debitAmount, bank.transaction_date as transactionDate, bank.transaction_name as transactionName, receipt.cr_date as crDate, receipt.picture_reference as pictureReference, receipt.receipt_date as receiptDate, receipt.reimbursment as reimbursment, receipt.total_amount as totalAmount, receipt.vendor as vendor " +
"from bank inner join receipt on bank.debit_amount=receipt.total_amount where ((bank.transaction_date >= receipt.receipt_date) and (bank.transaction_date <= DATE_ADD(receipt.receipt_date, INTERVAL 5 DAY) ))"//sample native query
def data = currentSession.createSQLQuery(q)
data.setResultTransformer(Criteria.ALIAS_TO_ENTITY_MAP);//if you are using alias for query e.g bank.credit_amount as creditAmount
final result = data.list()
return result
}
}

Hibernate query for employee with date

This is my code.. Query working when i search with mysql query(find it in screenshot).But failed with hiberbate query.
EmployeeAttendanceMaster masterEmployeeFromRepository = masterEmployeeRepository.findById(employee, date);
if (masterEmployeeFromRepository == null) {
System.out.println("SignIn Successfully");
}else System.out.println("You are already Logged In");
masterEmployeeRepository:
#Query("select me from EmployeeAttendanceMaster me where me.employee = ?1 and Date(me.date) = ?2 order by me.date desc")
EmployeeAttendanceMaster findById(Employee employee,Date date);
mysql db screenshot in with same query
Data with same date there in db..So it shoudnot go through if condition.It should follow else condition.But as long as i tried this it prints "SignIn Successfully"
Thanks advance
You are using the Spring Data JPA #Query annotation (as discerned from the full data type you have provided in the comments to your question). The query you specify with #Query (select me from EmployeeAttendanceMaster me ...) must be a valid JPA Query Language (JPQL) statement. From what I know and remember, JPQL does not have a Date() function. So, your query is invalid because it contains Date(me.date) which refers to a non-existent JPQL Date() function, even if you can run it directly on MySQL.
You can change your query declaration to:
#Query(value = "select * from EmployeeAttendanceMaster where employee_id = ?1 and Date(date) = ?2 order by date desc", nativeQuery = true)
This will force the JPA provider (Hibernate in your case) to treat the query as a native SQL query and will be executed on the underlying database without any translation. You will lose database independence though.

HQL Query fails in Hibernate MySQL

I want to recuperate all rows from user table.
String queryS = "select u from user u";
System.out.println("entityManager: "+(entityManager == null));
Query query = entityManager.createQuery(queryS);
//staff
The line that throws the exception is Query query = entityManager.createQuery(queryS);
I don't know why even persistance file is ok and the table exists
The stack is:
10:36:06.693 [AWT-EventQueue-0] DEBUG org.hibernate.hql.ast.ErrorCounter - throwQueryException() : no errors
10:36:06.693 [AWT-EventQueue-0] DEBUG o.h.hql.antlr.HqlSqlBaseWalker - select << begin [level=1, statement=select]
You have to put the name of the table in the query as in the persistence file not in database.
If this:
String queryS = "select u from user u"
Is referred on table name you can't use createQuery method but createNativeQuery
If you want to use createQuery you must use in your query the entity/class mapped youe user table
Summarizing:
Case 1 (use createNativeQuery)
String queryS = "select u from user u";
Query query = entityManager.createNativeQuery(queryS);
Case 2 (use createQuery)
String queryS = "select u from " + User.class.getName() + " u";
Query query = entityManager.createNativeQuery(queryS);

Complex MySQL query issue

I have a somewhat complex mySQL query I am trying to execute. I have two parameters: facility and isEnabled. Facility can have a value of "ALL" or be specific ID. isEnabled can have value of "ALL" or be 0/1.
My issue is that I need to come up with logic that can handle the following scenarios:
1) Facility = ALL AND isEnabled = ALL
2) Facility = ALL AND isEnabled = value
3) Facility = someID AND isEnabled = ALL
4) Facility = someID AND isEnabled = value
The problem is that I have several nested IF statements:
IF (Facility = 'ALL') THEN
IF (isEnabled = 'ALL') THEN
SELECT * FROM myTable
ELSE
SELECT * FROM myTable
WHERE isEnabled = value
END IF;
ELSE
IF (isEnabled = 'ALL') THEN
SELECT * FROM myTable
WHERE facility = someID
ELSE
SELECT * FROM myTable
WHERE facility = someID AND isEnabled = value
END IF;
END IF;
I would like to be able to combine the logic in the WHERE clause using either a CASE statement or Conditional's (AND/OR) but I am having trouble wrapping my head around it this morning. Currently the query is not performing as it is expected to be.
Any insight would be helpful!
Thanks
You could do this...
SELECT
*
FROM
myTable
WHERE
1=1
AND (facility = someID OR Facility = 'ALL')
AND (isEnabled = value OR isEnabled = 'ALL')
However, this yields a poor execution plan - it's trying to find one size fits all, but each combination of parameters can have different plans depending on data, indexes, etc.
This means that it is better to build the query dynamically
SELECT
*
FROM
myTable
WHERE
1=1
AND facility = someID -- Only include this line if : Facility = 'ALL'
AND isEnabled = value -- Only include this line if : isEnabled = 'ALL'
I know it can feel dirty to use dynamic queries, but this is a good corner case as to when then really can excel. I'll go find a spectacularly informative link for you now. (It's a lot to read, but it's very worth learning from)
Link : Dynamic Search