2

Possible Duplicate:
Using Hibernate query : colon gets treated as parameter / escaping colon

We are trying to write a native query. When we try to update a particular column value that contains a ": " ,we get an exception.

This is the generated query

  UPDATE MY_TABLE SET DESCRIPTION = "Test 01 : ABC",LAST_UPDATE_TS =
  CURRENT_TIMESTAMP ,LAST_UPDATE_USER_ID = 111 WHERE MY_ID =123 

I think the problem lies in the DESCRIPTION data, which contains ': '

We get this error

 nested exception is org.hibernate.QueryException:Space is not allowed after 
 parameter prefix ':' ' UPDATE 
 MY_TABLE SET DESCRIPTION = "MY Test 01 : ABC",LAST_UPDATE_TS =
 CURRENT_TIMESTAMP, LAST_UPDATE_USER_ID = 111 WHERE MY_ID =123'

This is the Java code that is responsible for the query :

 StringBuffer strQry = new StringBuffer(" UPDATE MY_TABLE SET ");

          if(myForm.getDescription() != null){
                 if(flag == 1){
                       strQry.append(",");
                 }
                 strQry.append(" DESCRIPTION = \"" + myForm.getDescription().trim()+ "\" ");
                 flag = 1;

Any idea why this error is occurring and how we can get around it ?

Community
  • 1
  • 1
user2434
  • 6,339
  • 18
  • 63
  • 87

3 Answers3

1
UPDATE MY_TABLE SET DESCRIPTION = "Test 01 \\: ABC",LAST_UPDATE_TS =
  CURRENT_TIMESTAMP ,LAST_UPDATE_USER_ID = 111 WHERE MY_ID =123

add forward slashes.

The colon is used to specify named parameters so you have to escape it(and then escape the escape).

NimChimpsky
  • 46,453
  • 60
  • 198
  • 311
0

You need to parameterize your sql. ":" is a special character that hibernate uses to detect named parameters. So, hibernate throws an exception when trying to parse your query.
You could parameterize your sql shown below.

   StringBuffer strQry = new StringBuffer(" UPDATE MY_TABLE SET ");

          if(myForm.getDescription() != null){
                 if(flag == 1){
                       strQry.append(",");
                 }
                 strQry.append(" DESCRIPTION = :description");
                 flag = 1;
....

   if(myForm.getDescription() != null){
        session.setString("description", description)
   }

Parameterizing your query is important for two other reasons -

  1. Avoid sql injections.
  2. Performance gains because of pre-compilation of your sql.
Sashi
  • 1,977
  • 16
  • 15
0

I think problem in you case occurs because Hibernate thinks that you are using named parameter (symbol ":" is a special keyword used for this). Try to define description, last_update_user_id and my_id as named parameter for your query. So your code will look like:

String queryText = "UPDATE MY_TABLE SET DESCRIPTION = :description,LAST_UPDATE_TS =
  CURRENT_TIMESTAMP, LAST_UPDATE_USER_ID = :lastUpdateUserID WHERE MY_ID = :myId";
Query query = session.createSQLQuery(queryText);
query.setParameter("description", yourDescription);
query.setParameter("lastUpdateUserID", yourLastUpdateUserID);
query.setParameter("myId", yourMyId);
...

In my example I define whole query in one place, but you may build it by parts like in your code snippet:

 StringBuffer strQry = new StringBuffer(" UPDATE MY_TABLE SET ");

 if(myForm.getDescription() != null){
     if(flag == 1){
           strQry.append(",");
     }
     strQry.append(" DESCRIPTION = :description ");
     flag = 1;
 } 
...

EDIT

In you conditions may be even better to use numeric parameters (?1) in query. Example:

 List<Object> parametersList = new LinkedList<Object>();
 int parameterPosition = 1;

 StringBuffer strQry = new StringBuffer(" UPDATE MY_TABLE SET ");

 if(myForm.getDescription() != null){
     if(parameterPosition > 1){
           strQry.append(",");
     }
     strQry.append(" DESCRIPTION = ?");
     strQry.append(parameterPosition);
     strQry.append(" ");

     parametersList.add(myForm.getDescription().trim());
     parameterPosition ++;
 } 
...

int position = 1;
for (Object parameter: parametersList) {
     query.setParameter(position, parameter);
     position++;
}

An least somehow like this).

dimas
  • 6,033
  • 36
  • 29