I'm trying to use hiberate query for quite alot of SQL, is there a way to rewrite this sql to make it cleaner. I'm also getting variable is never used for'Query paymentdate'
public void addPrevious(TodaysDate Date){
String paymentDate = ("SELECT PAYMENTDATE FROM table1 where DATE = (SELECT ID FROM _DATE WHERE ID = ( SELECT MAX(ID) FROM _DATE WHERE ID < ( SELECT MAX(ID) FROM _DATE ) ))");
String reportingUnit = ("SELECT REPORTING_UNIT FROM table1 where DATE = (SELECT ID FROM _DATE WHERE ID = ( SELECT MAX(ID) FROM _DATE WHERE ID < ( SELECT MAX(ID) FROM _DATE ) ))");
String insertLastDate = ("INSERT INTO table1(PAYMENTDATE, REPORTING_UNIT, Date) VALUES ("+id+" ,"+paymentDate+", "+amount+", "+asOfDate+")");
Query paymentdate = getSession().createQuery(paymentDate);
Query report = getSession().createQuery(reportingunit);
}
Related
I'm trying to execute the following SQL query writing native query in JPA:
SELECT id FROM (
SELECT DISTINCT id, DENSE_RANK() OVER (ORDER BY id) AS row FROM table
) WHERE row BETWEEN 1 AND 10;
In the Query annotation I wrote:
#Query(value = "SELECT t.id FROM (SELECT DISTINCT(e.id), DENSE_RANK() OVER (ORDER BY e.id) AS row FROM Table e) t WHERE row BETWEEN ? AND ?")
but I have syntax errors here FROM (SELECT.
Please, can you help me?
You have probably forgot nativeQuery=true
Try this:
#Query(value = "SELECT t.id FROM (SELECT DISTINCT(e.id), DENSE_RANK() OVER (ORDER BY e.id) AS row FROM Table e) t WHERE row BETWEEN ? AND ?", nativeQuery = true)
The Query on executing in PostgreSQL Database is fetching the records properly. But, when implemented using createnativeQuery, I am getting Error
ERROR SqlExceptionHelper:131 - ERROR: syntax error at or near ":"
Query Executed successfully in Postgres Database is mentioned below
select d.dt::date as date_current,
coalesce(underwriter_daily_cap, daily_file_cap) as file_cap,
user_id
from generate_series(date '2019-04-05', date '2019-04-09', interval '1'
day) as d(dt)
left join (
select upd.*, ud.daily_file_cap
from mod_underwriter_daily_file_count upd
join lsa_assignment_details ud on ud.user_id = upd.user_id
where ud.user_id = 350
) upd on upd.date_current = d.dt::date
ORDER BY d.dt DESC;
DAO Layer code is as follows
#SuppressWarnings("unchecked")
public List<Object[]> getUnderWriterCap(String dynamicUserId) {
log.info("Entered UserSkillMappingHibDAO :
getUnderWriterCap");
Session session = sessionFactory.getCurrentSession();
Date currentDateMinusFive =
DateUtil.getLastFiveDayOldPSTDate();
Date currentDate = DateUtil.getCurrentPSTDate();
String queryString = " select d.dt::date as date_current,
coalesce(underwriter_daily_cap, daily_file_cap) as file_cap, user_id "
+" from generate_series ( date '"+DateUtil.getDateFormat(currentDateMinusFive)+"', date '"+DateUtil.getDateFormat(currentDate)+"', INTERVAL '1' DAY ) as d(dt) "
+" left join ( select upd.*, ud.daily_file_cap from mod_underwriter_daily_file_count upd "
+" join lsa_assignment_details ud on ud.user_id = upd.user_id where ud.user_id = "+ dynamicUserId
+") upd on upd.date_current = d.dt::date ORDER BY d.dt DESC " ;
List<Object[]> records = session.createNativeQuery(queryString)
.getResultList();
return records;
}
The Exception got in console while executing the above code is as below
Hibernate: select d.dt:date as date_current, coalesce(underwriter_daily_cap, daily_file_cap) as file_cap, user_id from generate_series ( date '2019-04-04', date '2019-04-09', INTERVAL '1' DAY ) as d(dt) left join ( select upd.*, ud.daily_file_cap from mod_underwriter_daily_file_count upd join lsa_assignment_details ud on ud.user_id = upd.user_id where ud.user_id = 403) upd on upd.date_current = d.dt:date ORDER BY d.dt DESC
2019-04-09 18:58 ERROR SqlExceptionHelper:131 - ERROR: syntax error at or near ":"
Position: 14
There are several errors in this. More important than the syntax error is how you're appending a parameter as a string literal.
Instead of:
session.createNativeQuery("select * from tbl where param = '" + value + "'");
You have to use prepared statements (that is the term to look-up). This is extremely important for security.
Query q = session.createNativeQuery("select * from tbl where param = :par1");
q.setParameter("par1", value);
Now as for the syntax error, it's caused by your use of PostgreSQL's custom typecast syntax. You have to replace it with the standard SQL typecast from d.dt::date to cast(d.dt as date), because Hibernate expects : to be the start of a named parameter.
String queryString = "select cast(d.dt as date) as date_current, "
+" coalesce(underwriter_daily_cap, daily_file_cap) as file_cap, user_id "
+" from generate_series ( current_date - 5, current_date, INTERVAL '1' DAY ) as d(dt) "
+" left join ( select upd.*, ud.daily_file_cap from mod_underwriter_daily_file_count upd "
+" join lsa_assignment_details ud on ud.user_id = upd.user_id where ud.user_id = :dynuid ) upd on upd.date_current = cast(d.dt as date) ORDER BY d.dt DESC " ;
List<Object[]> records = session.createNativeQuery(queryString)
.setParameter("dynuid", dynamicUserId)
.getResultList();
I also replaced you current date java calculations with database functions. Instead of doing:
Date currentDateMinusFive = DateUtil.getLastFiveDayOldPSTDate();
Date currentDate = DateUtil.getCurrentPSTDate();
...
.setParameter("ds", DateUtil.getDateFormat(currentDateMinusFive))
.setParameter("de", DateUtil.getDateFormat(currentDate))
You have the database do it for you using current_date - 5 and current_date.
Another thing you should watch-out for, since your DateUtil is using the old java.util.Date class and related stuff is that if you are using a SimpleDateFormatter to format it, then it must be a new instance on every call. Do not optimize it to a static final, because it's not thread-safe. I've suffered from this.
edit: I also believe your query can be optimized much further into this, and it will have the same results:
select upd.date_current, underwriter_daily_cap, daily_file_cap from mod_underwriter_daily_file_count upd
join lsa_assignment_details ud on ud.user_id = upd.user_id
where ud.user_id = :dynuid and
upd.date_current between current_date - 5 and current_date
ORDER BY d.dt DESC
Notice I removed some fields from the select, like user_id, because you are already telling the database which one you want. The one major difference is this query will skip results for days with no entries.
The Query:
SELECT DISTINCT UNIQUEID,ID
FROM
(
(SELECT UNIQUEID, DATE, ID
FROM stackscontents
WHERE BACKGROUND IS NOT NULL
AND TITLE IS NOT NULL
AND ID < ?
ORDER BY DATE DESC limit 1)
UNION ALL
(SELECT UNIQUEID, DATE, ID
FROM stackscontents
WHERE BACKGROUND IS NOT NULL
AND TITLE IS NOT NULL
AND ID > ?
ORDER BY DATE ASC limit 1)
)
UNION ALL (
(SELECT UNIQUEID, DATE, ID
FROM sharedlinks
WHERE ID < ?
ORDER BY DATE DESC limit 1)
UNION ALL
(SELECT UNIQUEID, DATE, ID
FROM sharedlinks
WHERE ID > ?
ORDER BY DATE ASC limit 1)
) t
To be precise, I am trying to get a row before another row from 2 tables. But I am getting syntax error as below:
com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Every derived table must have its own alias
Below is the code where I am using the query:
if (NewDetails == null) {
query2 = "SELECT DISTINCT UNIQUEID,ID FROM ((SELECT UNIQUEID, DATE, ID FROM stackscontents WHERE BACKGROUND IS NOT NULL AND TITLE IS NOT NULL AND ID < ? ORDER BY DATE DESC limit 1) UNION ALL (SELECT UNIQUEID, DATE, ID FROM stackscontents WHERE BACKGROUND IS NOT NULL AND TITLE IS NOT NULL ID > ? ORDER BY DATE ASC limit 1)) UNION ALL "
+ "((SELECT UNIQUEID, DATE, ID FROM sharedlinks WHERE ID < ? ORDER BY DATE DESC limit 1) UNION ALL (SELECT UNIQUEID, DATE, ID FROM sharedlinks WHERE ID > ? ORDER BY DATE ASC limit 1)) t ";
try {
DBConnect Database = new DBConnect();
Connection con = null;
PreparedStatement ps = null;
ResultSet rs = null;
try {
con = Database.getcon();
ps = con.prepareStatement(query2);
ps.setInt(1, minID);
ps.setInt(2, minID);
ps.setInt(3, minID);
ps.setInt(4, minID);
rs=ps.executeQuery();
while(rs.next()) {
minID = rs.getInt(2);
parts[i] = rs.getString(1);
i--;
}
} finally {
if (ps != null)
ps.close();
if (rs != null)
rs.close();
if (con != null)
con.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
}
unfortunately it also does not return expected row - 1, but it returns 451 from stackscontents which is the first row. as below:
Stackscontents:
stackscontents table rows
sharedlinks:
sharedlinks table rows
Your parenthesis are messing things up. Here is your code reformatted to show why:
SELECT DISTINCT UNIQUEID,ID
FROM (
(SELECT UNIQUEID, DATE, ID FROM stackscontents WHERE BACKGROUND IS NOT NULL AND TITLE IS NOT NULL AND ID < ? ORDER BY DATE DESC limit 1)
UNION ALL
(SELECT UNIQUEID, DATE, ID FROM stackscontents WHERE BACKGROUND IS NOT NULL AND TITLE IS NOT NULL AND ID > ? ORDER BY DATE ASC limit 1)
)
UNION ALL
(
(SELECT UNIQUEID, DATE, ID FROM sharedlinks WHERE ID < ? ORDER BY DATE DESC limit 1)
UNION ALL
(SELECT UNIQUEID, DATE, ID FROM sharedlinks WHERE ID > ? ORDER BY DATE ASC limit 1)
) t
No wonder the SQL parser goes "Huh?"
Your code should be:
SELECT DISTINCT UNIQUEID,ID
FROM (
(SELECT UNIQUEID, DATE, ID FROM stackscontents WHERE BACKGROUND IS NOT NULL AND TITLE IS NOT NULL AND ID < ? ORDER BY DATE DESC limit 1)
UNION ALL
(SELECT UNIQUEID, DATE, ID FROM stackscontents WHERE BACKGROUND IS NOT NULL AND TITLE IS NOT NULL AND ID > ? ORDER BY DATE ASC limit 1)
UNION ALL
(SELECT UNIQUEID, DATE, ID FROM sharedlinks WHERE ID < ? ORDER BY DATE DESC limit 1)
UNION ALL
(SELECT UNIQUEID, DATE, ID FROM sharedlinks WHERE ID > ? ORDER BY DATE ASC limit 1)
) t
Currently i'm using PostgreSQL database in my Spring MVC web application. I'm able to get the values when i execute the query in PgAdmin tool.
In my query, I'm trying to join 4 tables and get the values.
My query is:
SELECT (s.school_id, u.first_name, u.last_name, u.username, u.email, p.plan_name, s.start_date, s.end_date, s.subscription_price, (SELECT COUNT(*) FROM school_user t WHERE t.user_type = 'T' and t.school_id = s.school_id), (SELECT COUNT(*) FROM school_user t WHERE t.user_type = 'A' and t.school_id = s.school_id), (SELECT COUNT(*) FROM school_user t WHERE t.user_type = 'S' and t.school_id = s.school_id)) FROM school s inner join user u on s.user_created = u.user_id inner join plan p on s.current_plan = p.plan_Id where s.application_id = 30 and s.site_id = 42;
When I use this same query in my Dao method, I'm getting error like:
No Dialect mapping for JDBC type: 1111
Code used in dao method:
public List<Object[]> getInformationValues(int applicationId, int siteId) throws HibernateException {
Session session = getCurrentSession();
Query query = session.createSQLQuery("SELECT (s.school_id, u.first_name, u.last_name, u.username, u.email, p.plan_name, s.start_date, s.end_date, s.subscription_price, (SELECT COUNT(*) FROM school_user t WHERE t.user_type = 'T' and t.school_id = s.school_id), (SELECT COUNT(*) FROM school_user t WHERE t.user_type = 'A' and t.school_id = s.school_id), (SELECT COUNT(*) FROM school_user t WHERE t.user_type = 'S' and t.school_id = s.school_id)) FROM school s inner join user u on (s.user_created = u.user_id) inner join plan p on (s.current_plan = p.plan_Id) where s.application_id = :applicationId and s.site_id = :siteId") .setParameter("applicationId", applicationId) .setParameter("siteId", siteId);
List<Object[]> results = query.list();
return results;
}
Is there any way to fix this issue?
Hi im trying to get number of rows from table using Hibernate based on start and end Date but im Getting not a Valid Month error
Session session = sessionFactory.getCurrentSession();
startDate = "13-02-02 00:00:00";
endDate = "17-02-02 00:00:00";
try{
String hql = "select Count(*) from mytable where PERIOD_START_DATETIME between '"
+ startDate + "' AND '" + endDate + "'";
Query query = session.createQuery(hql);
long count=(long) query.uniqueResult();
return count;
} finally{
session.close();
}
This is my table description
Name NULL TYPE
NAME NOT NULL VARCHAR2(255 CHAR)
PERIOD_END_DATETIME NOT NULL TIMESTAMP(6)
PERIOD_START_DATETIME NOT NULL TIMESTAMP(6)
PROD_OFFER_TERM_TYPE_ID NOT NULL NUMBER(19)
Using string concatenation for generating SQL queries is usually a bad idea because
it's bad for performance (causes re-parsing of the SQL statement for every execution)
it's prone to SQL injection attacks
HQL supports bind variables / prepared statements, so this should work:
String hql = "select Count(*) from mytable where PERIOD_START_DATETIME between :startdate AND :enddate ";
Query query = session.createQuery(hql);
query.setParameter("startdate", startDate);
query.setParameter("enddate", endDate);
(where startDate and endDate are actual java.sql.Timestamp values, not strings).
As the start/end times are SQL TIMESTAMPs in the DB, you can pass in a Timestamp object into the query as follows:
Session session = sessionFactory.getCurrentSession();
final DateFormat df = new SimpleDateFormat("yy-MM-dd");
// omitting the time part will set the time to midnight (00:00:00)
Timestamp start = new Timestamp(df.parse("13-02-02").getTime());
Timestamp end = new Timestamp(df.parse("17-02-02").getTime());
try {
String hql =
"select Count(*) from mytable where PERIOD_START_DATETIME between ? AND ?";
Query query = session.createQuery(hql)
.setTimestamp(0, start)
.setTimestamp(1, end);
long count = (long) query.uniqueResult();
return count;
} finally {
session.close();
}
Make sure you actually pass date values in your query.
You can use the to_date function where you specify the format of the date, as it is represented in the string.
select Count(*)
from mytable
where PERIOD_START_DATETIME between to_date(startDate,'DD-MM-YYYY HH24:MI:SS') AND to_date(endDate,'DD-MM-YYYY HH24:MI:SS');
select Count(*)
from mytable
where PERIOD_START_DATETIME between TO_TIMESTAMP(:startDate, 'YY-MM-DD HH24:MI:SS') AND TO_TIMESTAMP(:endDate, 'YY-MM-DD HH24:MI:SS')