-->
These old forums are deprecated now and set to read-only. We are waiting for you on our new forums!
More modern, Discourse-based and with GitHub/Google/Twitter authentication built-in.

All times are UTC - 5 hours [ DST ]



Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 13 posts ] 
Author Message
 Post subject: Saving Bug?
PostPosted: Wed May 28, 2008 12:20 pm 
Newbie

Joined: Wed May 28, 2008 11:30 am
Posts: 9
Table:
CREATE TABLE `message` (
`id` int(11) NOT NULL auto_increment,
`folder` int(11) NOT NULL,
`uid` varchar(50) NOT NULL,
`from` varchar(50) NOT NULL,
`to` text NOT NULL,
`content` text,
`dateLastModified` timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

When use hibernate to save one message into my db (I use MySQL).
it will create a sql script:
insert into message(...,from,...) values (...);
Of course, this sql script is wrong, because of the key word "from".

I found the source code to generate the sql script is:
org.hibernate.sql.Insert.Java:
.............
buf.append("insert into ")
.append(tableName);
if ( columns.size()==0 ) {
buf.append(' ').append( dialect.getNoColumnsInsertString() );
}
else {
buf.append(" (");
Iterator iter = columns.keySet().iterator();
while ( iter.hasNext() ) {
buf.append( iter.next() );
if ( iter.hasNext() ) {
buf.append( ", " );
}

}
buf.append(") values (");
............

to fix the problem,
we could do like this:
insert into message(...,`from`,...) values (...);(in MySQL, I am not sure in other Database, such as MSSQL).

so the code should be like this:

buf.append("insert into ")
.append(tableName);
if ( columns.size()==0 ) {
buf.append(' ').append( dialect.getNoColumnsInsertString() );
}
else {
buf.append(" (");
Iterator iter = columns.keySet().iterator();
while ( iter.hasNext() ) {
buf.append("`");//Bill Add, to avoid key word for sql script
buf.append( iter.next() );
buf.append("`");//Bill Add

if ( iter.hasNext() ) {
buf.append( ", " );
}
}
buf.append(") values (");

Thus, It works!!!

I think this is a small bug of hibernate, am I right?

How Can I report to Hibernate org?

thx for reading!!!


Top
 Profile  
 
 Post subject: Saving Bug?
PostPosted: Wed May 28, 2008 12:36 pm 
Newbie

Joined: Wed May 28, 2008 11:30 am
Posts: 9
could use

/**
* The character specific to this dialect used to begin a quoted identifier.
*
* @return The dialect's specific open quote character.
*/
public char openQuote() {
return '"';
}

/**
* The character specific to this dialect used to close a quoted identifier.
*
* @return The dialect's specific close quote character.
*/
public char closeQuote() {
return '"';
}

in Dialect (sub) class.


Top
 Profile  
 
 Post subject: Re: Saving Bug?
PostPosted: Wed May 28, 2008 12:36 pm 
Expert
Expert

Joined: Wed Apr 11, 2007 11:39 am
Posts: 735
Location: Montreal, QC
Hibernate will have to stay database neutral, so probably this is not a good enough solution. However, you can modify your mappings and put those quotes around column names. In case of SqlServer hibernate generated the right sql for me when I put column names in brackets which is sql server's keyword delimiter.


Farzad-


Top
 Profile  
 
 Post subject: Saving Bug?
PostPosted: Wed May 28, 2008 12:38 pm 
Newbie

Joined: Wed May 28, 2008 11:30 am
Posts: 9
so it should be change to:

buf.append(dialect.openQuote());//Bill Add, to avoid key word for sql script
buf.append( iter.next() );
buf.append(dialect.closeQuote());//Bill Add


Top
 Profile  
 
 Post subject: Saving Bug?
PostPosted: Wed May 28, 2008 12:44 pm 
Newbie

Joined: Wed May 28, 2008 11:30 am
Posts: 9
Farzad, you are right.

however, it seams using Dialect openQuote and closeQuote is better.

and I check SQL server dialect, they are
....
Code:
   public char closeQuote() {
      return ']';
   }

   public char openQuote() {
      return '[';
   }


......

and mysql dialect

Code:
   public char closeQuote() {
      return '`';
   }

   public char openQuote() {
      return '`';
   }


...

right?


Top
 Profile  
 
 Post subject: Re: Saving Bug?
PostPosted: Wed May 28, 2008 1:08 pm 
Expert
Expert

Joined: Wed Apr 11, 2007 11:39 am
Posts: 735
Location: Montreal, QC
You have a point there. I digged into HB code and it appears that those values are used if a column is quoted with quotes. This is the code from HB code:


Code:
   public final String quote(String column) {
      if ( column.charAt( 0 ) == '`' ) {
         return openQuote() + column.substring( 1, column.length() - 1 ) + closeQuote();
      }
      else {
         return column;
      }
   }



Give it a try and see if it appears properly on insert commands. You still need to change mappings though.


Farzad-


Top
 Profile  
 
 Post subject: Saving Bug?
PostPosted: Wed May 28, 2008 2:00 pm 
Newbie

Joined: Wed May 28, 2008 11:30 am
Posts: 9
thx Farzad.

I have check that quote method is used at org.hibernate.sql.Template renderOrderByStringTemplate and renderWhereStringTemplate,
the codes are:
Code:
               result.append(TEMPLATE)
               .append('.')
               .append( dialect.quote(token) );

and
Code:
               result.append(placeholder)
               .append('.')
               .append( dialect.quote(token) );


it seams no problem, (because it has "*.*", it will not have problem.).

The reason why I want to change the Insert class is that:
usually, the user just care about the column name, doesn't care about the name is keyword or not (I think). If the the name is key word, as you suggested, it should change the mapping name (add the quote). it doesn't like what we usually do.
so, for more easier to use, I suggest to change the Insert Class.

Code:
            buf.append(dialect.openQuote());//to avoid key word for sql script
            buf.append( iter.next() );
            buf.append(dialect.closeQuote());//


improve HB, right?
^-^


Top
 Profile  
 
 Post subject: Re: Saving Bug?
PostPosted: Wed May 28, 2008 2:41 pm 
Expert
Expert

Joined: Wed Apr 11, 2007 11:39 am
Posts: 735
Location: Montreal, QC
Bill Wang wrote:
improve HB, right?
^-^



Sure thing. The only thing I am not sure is that what that column name collection contains. There is a chance that the collection holds the right column name if it is quoted properly in mappings. If so, the solution you are suggesting will add extra quotes to an already quoted column name.



Farzad-


Top
 Profile  
 
 Post subject: Saving Bugs
PostPosted: Wed May 28, 2008 11:11 pm 
Newbie

Joined: Wed May 28, 2008 11:30 am
Posts: 9
I C,
We could do like quote method in Dialect.
Code:
   public final String quote(String column) {
      if ( column.charAt( 0 ) == '`' ) {
         return openQuote() + column.substring( 1, column.length() - 1 ) + closeQuote();
      }
      else {
         return column;
      }
   }


Test it whether contains quote first.
so:
Code:
            if(columnName.charAt(0) != dialect.openQuote())//hava quote or not?
               buf.append(dialect.openQuote());//add quote to avoid key word for sql script


Ok?


Top
 Profile  
 
 Post subject: Re: Saving Bugs
PostPosted: Thu May 29, 2008 11:10 am 
Expert
Expert

Joined: Wed Apr 11, 2007 11:39 am
Posts: 735
Location: Montreal, QC
Bill Wang wrote:
Ok?


Naha, I did a small test and hibernate does change quoted columns while inserting. So here is my entity xml file:

Code:
<hibernate-mapping>
    <class name="test.model.data.Entity1" table="ENT1" lazy="true">

        <composite-id name="id" class="test.model.data.Entity1Key">
            <key-property name="id" column="ID" type="long"/>
            <key-property name="anotherId" column="ANOTHER_ID" type="long"/>
        </composite-id>

        <property name="name" type="string" lazy="true" column="`Name`"/>
        <property name="otherId" type="long" column="THE_OTHER_ID"/>
    </class>

</hibernate-mapping>


and here is the insert sql hibernate generated:

Code:
insert
    into
        ENT1
        ([Name], THE_OTHER_ID, ID, ANOTHER_ID)
    values
        (?, ?, ?, ?)


You can see hibernate has actually converted my quotes to sql server quotes, which is the database/dialect I used for testing. In this case there is no need for modifying hibernate code.


Farzad-


Top
 Profile  
 
 Post subject: Saving Bugs
PostPosted: Thu May 29, 2008 8:59 pm 
Newbie

Joined: Wed May 28, 2008 11:30 am
Posts: 9
oh I C.
How about the key world "from" or "order" or else?


Top
 Profile  
 
 Post subject: Saving Bugs
PostPosted: Thu May 29, 2008 9:03 pm 
Newbie

Joined: Wed May 28, 2008 11:30 am
Posts: 9
oh I C.
How about the key word "from" or "order" or else?


Top
 Profile  
 
 Post subject: Saving Bugs
PostPosted: Thu May 29, 2008 9:28 pm 
Newbie

Joined: Wed May 28, 2008 11:30 am
Posts: 9
i C
Farzad, your method is better, thx


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 13 posts ] 

All times are UTC - 5 hours [ DST ]


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.