JPA - subtract two date column - oracle

I have project using EJB3 + JPA(eclipselink) + Oracle database + glass-fish
everything work fine i can get any table from database
what I want is to execute this sql statement using JPQL
select de - sysdate as newde
from deinfo;
I try this code
factory = Persistence.createEntityManagerFactory(PERSISTENCE_UNIT_NAME);
EntityManager em = factory.createEntityManager();
// Read the existing entries and write to console
String qSelect = "SELECT d.de - CURRENT_Date as newde FROM Deinfo d ";
Query q = em.createQuery(qSelect);
but it's throw the error when create query
An exception occurred while creating a query in EntityManager:
Exception Description: Syntax error parsing [SELECT d.de - CURRENT_Date as newde FROM Deinfo d ].
[7, 19] The left expression is not an arithmetic expression.
why I can't subtract tow date using JPQL but I can use the same sql above inside Oracle sql command and work fine
I also try
select CURRENT_Date as newde
it's return the current date so no problem with command
it's just I can't use mathematics operation on date using JPQL

Related

Optional parameter in query does not work for db2 but works in oracle

Below query works fine for Oracle database, but for Db2 it throws error sqlcode -417.
I have looked up similar problems but did not get any definitive answer:
#Query(value = "select * from tableName f where (aC is null or f.a_c = aC)", nativeQuery = true)
Page<tablename> findByFilters(String aC, Pageable pageable);
On execution the error code is -417
One way to solve this problem would be to rewrite the query as the following:
select * from tableName f where f.a_c = coalesce(aC, f.a_c)
The form of query above is likely to be accepted. In order to find out the exact reason of the error you get, it is necessary to trace the actual SQL statement passed to Db2.
Another option of solving the problem may be to add the CAST operator, which would define the data type of your parameter:
select * from tableName f where (cast(aC as integer) is null or f.a_c = aC)
This is suggested in the description of the error you get

Oracle 18.1 sql query error

I have an sql query
SELECT ("SL/VL".TOTAL_SICK_LEAVE - SUM(EMPLOYEE_INFO.DAYS_TAKEN_SICK))
FROM EMPLOYEE_INFO
INNER JOIN "SL/VL"
ON EMPLOYEE_INFO.EMPLOYEE_NAME = "SL/VL".EMPLOYEE_NAME
where contract_year='Year 1'and
employee_info.EMPLOYEE_NAME = :P4_EMPLOYEE_NAME
GROUP BY "SL/VL".TOTAL_SICK_LEAVE
which was giving me the desired results when I had oracle apex 5.1. Now I upgraded my database to oracle 18.1 I am getting the"ORA-20999: Column name "("SL/VL".TOTAL_SICK_LEAVE-SUM(EMPLOYEE_INFO.DAYS_TAKEN_SICK))" is invalid for the LOV SQL query. Make sure that you use valid alias names for your columns."
It appears that 18.1 wants a column alias on the expression ("SL/VL".TOTAL_SICK_LEAVE - SUM(EMPLOYEE_INFO.DAYS_TAKEN_SICK)). Perhaps if you redo your SQL as
SELECT (s.TOTAL_SICK_LEAVE - SUM(e.DAYS_TAKEN_SICK)) AS SICK_LEAVE_REMAINING
FROM EMPLOYEE_INFO e
INNER JOIN "SL/VL" s
ON e.EMPLOYEE_NAME = s.EMPLOYEE_NAME
WHERE CONTRACT_YEAR = 'Year 1' AND
e.EMPLOYEE_NAME = :P4_EMPLOYEE_NAME
GROUP BY s.TOTAL_SICK_LEAVE
the database will be happier.

spring jpa handling null value in max query

I'm trying to select a sequence id from the database using this query:
#Query("select max(pi.sequence) + 1 from ProductImage pi where pi.product = :product")
int nextSequenceForProduct(#Param("product")Product product);
It works well except when there's no values in the table, it throws some type of null value exception from the JPA code.
Is there a way to handle null values in spring jpa? For example something like this SQL:
select ifnull(max(pi.sequence),1) from ....
you can use nvl() function and change the query to native query or named native query to avoid the exception
#NativeQuery("select nvl(max(pi.sequence),0) + 1 from ProductImage pi where pi.product = :product")

getting Hibernate error when using DBMS_RANDOM.value

I would like to achieve same result as the below query using Hibernate SQL, i.e., I would like to get two random records from the table whose ID is not equal to 300. I am using Hibernate 4.1 and Oracle 11g. I ran the below query on Toad and it gives 2 random records. But, when I try to run the HQL, there is error to do with the usage of "DBMS_RANDOM.value".
SELECT * FROM
( SELECT *
FROM table
where ID != '300'
AND q_ID=125
ORDER BY DBMS_RANDOM.value
)WHERE rownum < 3
;
I tried creating criteria and query, but both give Hibernate errors:
Hibernate Message: Invalid path: 'DBMS_RANDOM.RANDOM' [from com.model.table tab where tab.ID != '33092' ORDER BY DBMS_RANDOM.RANDOM]
and my actual hibernate query is:
Query query = session.createQuery("from table tab where tab.ID != '" +agrmId+"' ORDER BY DBMS_RANDOM.RANDOM").setMaxResults(2);
I also tried ORDER BY rand() and that gives an Oracle error.
Thank you for any help.
I solved the problem by adding a property tag in the hibernate mapping file:
<property name="constVal" formula="DBMS_RANDOM.RANDOM" type="long"/>
and then, in the POJO class, I added a variable with getter and setter methods:
private long constVal;
then, in the DAO class, I added the following query:
Criteria crit1 = session.createCriteria(table.class);
crit1.add(Restrictions.ne("id",300));
crit1.add(Restrictions.eq("quesId",125));
crit1.addOrder(Order.asc("constVal"));
crit1.setMaxResults(2);
and that solved it.

Fetch dates (by month or year) stored in TIMESTAMP using JPA

I am facing a problem and I would like you to help me.
It turns out I have one table in my Oracle 11g database where I store failures of one electronic device. The table definition is following:
CREATE TABLE failure
( failure_id NUMERIC NOT NULL
, fecha TIMESTAMP NOT NULL
, module_id NUMERIC NOT NULL
, code NUMERIC
, PRIMARY KEY(failure_id)
);
Where 'fecha' means 'date'.
I need to fetch failures by YEAR or by MONTH for one specific module but I can't. My ORM maps the TIMESTAMP type to java.sql.Date but I don't know how to compare the month in the JPQL sentence. I have tried to use ORACLE functions with native queries but I front with another issue: to cast the results.
I am using JPA 2.0 with Eclipselink 2.3.2.
My doubts are:
Can I use Oracle functions with this version of Eclipselink library? My experience say no.
Query query = entityManager.createQuery("SELECT f FROM Failure f "
+ "WHERE EXTRACT(YEAR FROM f.fecha) = ?1 "
+ "AND f.moduleId.moduleId = ?2");
query.setParameter(1, year);
query.setParameter(2, idModule);
I get this error: Unexpected token [(]
Can I use Eclipselink functions? My experience say no.
Query query = entityManager.createQuery("SELECT f FROM Failure f "
+ "WHERE EXTRACT('YEAR', f.fecha) = ?1 "
+ "AND f.moduleId.moduleId = ?2");
query.setParameter(1, year);
query.setParameter(2, idModule);
Same error.
Do you know a simple way to fetch this data using only one query?
I know I can fetch one module and then check failures with loops but I think it is not the best performing solution.
Thanks.
My sources:
Eclipselink JPA functions link
Eclipselink Query Enhancements link
A native query is written in the SQL dialect of your DB so can use DB specific functionality see the createNativeQuery methods of the EntityManager.
However there is another solution, test the timestamp against a lower and upper value:
WHERE f.fecha >= '2012-9-1' AND f.fecha < '2012-10-1'
The syntax in EclipseLink 2.4 for EXTRACT is,
EXTRACT(YEAR, f.fecha)
http://wiki.eclipse.org/EclipseLink/UserGuide/JPA/Basic_JPA_Development/Querying/JPQL#Functions
I used Eclipselink v 2.4 functions and I am getting values using this:
Query query = entityManager.createQuery("SELECT f FROM Failure f "
+ "WHERE SQL('EXTRACT (YEAR FROM ?)', f.fecha) = ?1 "
+ "AND f.moduleId.moduleId = ?2 ");
Extracting year from date stored in database avoids to me one comparison between two dates.
Use
Query query = entityManager.createQuery("SELECT f FROM Failure f "
+ "WHERE EXTRACT(YEAR from f.fecha) = ?1 "
+ "AND f.moduleId.moduleId = ?2");
I was facing the same problem. I only checked for the correct syntax of that EXTRACT function for oracle and it worked for me! (Notice the FROM clause into the function syntax.
#NamedQuery(name = "Registros.findByFechacaptura", query = "SELECT s FROM Registros s WHERE EXTRACT(YEAR FROM s.fechacaptura) = EXTRACT(YEAR FROM :fechacaptura)")

Resources