Using Hibernate Queries - java

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

JPA select from select distinct

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)

Error while using generate_series in createNativeQuery

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.

How to select one row before another one - from a two tables SQL?

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

Using a Query, Joining 4 tables in Hibernate Mapping

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?

Not a Valid Month in Hibernate

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')

Categories