更新时出现Hibernate错误

时间:2012-11-11 15:39:25

标签: java sql oracle hibernate

  

可能重复:
  Using Hibernate query : colon gets treated as parameter / escaping colon

我们正在尝试编写本机查询。当我们尝试更新包含": "的特定列值时,我们会遇到异常。

这是生成的查询

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

我认为问题在于描述数据,其中包含': '

我们收到此错误

 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'

这是负责查询的Java代码:

 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;

知道为什么会出现这种错误以及我们如何解决它?

3 个答案:

答案 0 :(得分:1)

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

添加正斜杠。

冒号用于指定命名参数,因此您必须将其转义(然后转义转义)。

答案 1 :(得分:0)

您需要参数化您的sql。 “:”是hibernate用于检测命名参数的特殊字符。因此,在尝试解析查询时,hibernate会抛出异常 您可以参数化下面显示的sql。

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

由于其他两个原因,参数化查询非常重要 -

  1. 避免sql注入。
  2. 由于您的sql预编译,性能提升。

答案 2 :(得分:0)

我认为你遇到的问题是因为Hibernate认为你使用的是命名参数(符号“:”是一个用于此的特殊关键字)。尝试将description,last_update_user_id和my_id定义为查询的命名参数。所以你的代码看起来像:

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);
...

在我的示例中,我在一个地方定义了整个查询,但您可以按照代码段中的部分构建它:

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

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

修改

在您的情况下,在查询中使用数字参数(?1)可能更好。例如:

 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++;
}

至少在某种程度上是这样的。)