简体   繁体   中英

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM