Announcement

Collapse
No announcement yet.
X
  • Filter
  • Time
Clear All
new posts

    #16
    Found the root of the problem. Looks like the SmartClient handling of TINYINT will only work with the JDBC setting tinyInt1isBit=false, but the default is tinyInt1isBit=true. I guess now I need to figure out how to set tinyInt1isBit=false in server.properties. (But it seems like the default /should/ work. :-)

    From http://dev.mysql.com/doc/refman/5.5/en/connector-j-reference-type-conversions.html
    TINIYINT: "java.lang.Boolean if the configuration property tinyInt1isBit is set to true (the default) and the storage size is 1, or java.lang.Integer if not."

    ===== test ==================
    Code:
    import java.sql.*;
    
    public class TinyintJdbcTest {
    
       public static void main(String[] args) throws Exception {
          // Mysql JDBC defaults to tinyInt1isBit=true
          doIt(true);
          
          // But SmartClient code would only work if tinyInt1isBit=false
          doIt(false);
       }
    
       private static void doIt(boolean tinyInt1isBit) {
          System.out.println("\n--- testing with tinyInt1isBit = " + tinyInt1isBit + "------------------");
          try {
             Class.forName("com.mysql.jdbc.jdbc2.optional.MysqlDataSource");
             Connection connect = DriverManager
                   .getConnection("jdbc:mysql://localhost/myapp?user=myapp&password=changeme" +
                   		"&tinyInt1isBit=" + tinyInt1isBit);
    
             Statement statement = connect.createStatement();
             ResultSet resultSet = statement.executeQuery("SELECT id, enabled FROM SomeRule");
    
             writeResultSet(resultSet);
          } catch (Exception e) {
          }
       }
    
       private static void writeResultSet(ResultSet resultSet) throws SQLException {
          while (resultSet.next()) {
             String id = resultSet.getString("id");
             String enabled = resultSet.getString("enabled");
    
             Object obj = resultSet.getObject("enabled");
             String objType = obj.getClass().getName();
             Object result = "1".equals(obj.toString()) ? Boolean.TRUE : Boolean.FALSE;
    
             System.out.println("ID=" + id + ", enabled=" + enabled + ", objType=" + objType + ", result=" + result);
          }
       }
    
    }
    ===== output ==================
    Code:
    --- testing with tinyInt1isBit = true------------------
    ID=1, enabled=1, objType=java.lang.Boolean, result=false
    ID=2, enabled=0, objType=java.lang.Boolean, result=false
    
    --- testing with tinyInt1isBit = false------------------
    ID=1, enabled=1, objType=java.lang.Integer, result=true
    ID=2, enabled=0, objType=java.lang.Integer, result=false

    Comment


      #17
      Thanks for doing the legwork on this one, we'd be happy to add support for whatever MySQL is doing here - to clarify, it looks like you're seeing that with "tinyIntIsBit" is true, a Boolean is returned and obj.toString() is the string "true" - can you confirm?

      Comment


        #18
        That's right. I changed my test to print out the value of the 'obj'.

        This has become a blocker for me. Is there a way to change the setting?

        Code:
           private static void writeResultSet(ResultSet resultSet) throws SQLException {
              while (resultSet.next()) {
                 String id = resultSet.getString("id");
                 String enabled = resultSet.getString("enabled");
        
                 Object obj = resultSet.getObject("enabled");
                 String objType = obj.getClass().getName();
                 String objValue = obj.toString();
                 Object result = "1".equals(obj.toString()) ? Boolean.TRUE : Boolean.FALSE;
        
                 System.out.println("ID=" + id + ", enabled=" + enabled + ", objType=" + objType + ", objValue=" + objValue + ", result=" + result);
              }
           }
        Code:
        --- testing with tinyInt1isBit = false------------------
        ID=1, enabled=1, objType=java.lang.Integer, objValue=1, result=true
        ID=2, enabled=0, objType=java.lang.Integer, objValue=0, result=false
        
        --- testing with tinyInt1isBit = true------------------
        ID=1, enabled=1, objType=java.lang.Boolean, objValue=true, result=false
        ID=2, enabled=0, objType=java.lang.Boolean, objValue=false, result=false

        Comment


          #19
          I tried these settings in server.properties, but no luck so far...
          Code:
          sql.Mysql.interface.type: driverManager
          sql.Mysql.driver.url: jdbc:mysql://localhost/myapp?user=myapp&password=changeme&tinyInt1isBit=false
          ,chris

          Comment


            #20
            It'd be nice to be able to send arbitrary params. Maybe something like this in server.properties?
            Code:
            sql.Mysql.driver.tinyInt1isBit: false

            Comment


              #21
              Your JDBC URL should fix the problem, most likely, those settings aren't set as the default database (use the Admin Console to do this).

              However we're also adding code to just deal with whichever value MySQL sends (boolean or int) and this will appear in tomorrow's nightly build.

              Comment


                #22
                Thanks!

                Just to be clear.
                Does that mean you'll commit the change tomorrow or that it will be available in the download tomorrow AM?

                And thanks again!

                Comment


                  #23
                  Should be available in the builds which will appear in the early morning hours (Pacific) tomorrow.

                  Comment


                    #24
                    Has the patch made it in the nightly build yet? I downloaded a couple of times yesterday and again this morning (6:30 AM PST) but still see the same issue.

                    Comment


                      #25
                      Yes, it should be there - either 2.5.x or 3.x builds at SmartClient.com/builds have it.

                      Comment


                        #26
                        Hmmm. Well. It's still broken for me.
                        I just downloaded the 2.5 nightly again and got exactly the same results.

                        Comment


                          #27
                          I'm getting the error during an insert. Did you test the solution with insert and select?

                          Code:
                          === 2011-09-25 09:06:23,313 [l0-3] INFO  SQLDriver - [builtinApplication.SomeRule_add] Executing SQL update on 'Mysql': INSERT INTO SomeRule (enabled) VALUES ('false')
                          === 2011-09-25 09:06:23,331 [l0-3] WARN  RequestContext - dsRequest.execute() failed: 
                          java.sql.SQLException: Incorrect integer value: 'false' for column 'enabled' at row 1
                          	at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:1073)
                          	at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3603)
                          	at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3535)
                          	at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:1989)
                          	at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2150)
                          	at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2626)
                          	at com.mysql.jdbc.PreparedStatement.executeInternal(PreparedStatement.java:2119)
                          	at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:2415)
                          	at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:2333)
                          	at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:2318)
                          	at org.apache.commons.dbcp.DelegatingPreparedStatement.executeUpdate(DelegatingPreparedStatement.java:102)
                          	at com.isomorphic.sql.SQLDriver.doUpdate(SQLDriver.java:471)
                          	at com.isomorphic.sql.SQLDriver.update(SQLDriver.java:425)
                          	at com.isomorphic.sql.SQLDriver.executeUpdate(SQLDriver.java:545)
                          	at com.isomorphic.sql.SQLDataSource.executeNativeUpdate(SQLDataSource.java:388)
                          	at com.isomorphic.sql.SQLDataSource.SQLExecute(SQLDataSource.java:1341)
                          	at com.isomorphic.sql.SQLDataSource.processRequest(SQLDataSource.java:280)
                          	at com.isomorphic.sql.SQLDataSource.executeAdd(SQLDataSource.java:232)
                          	at com.isomorphic.datasource.DataSource.execute(DataSource.java:1156)
                          	at com.isomorphic.application.AppBase.executeDefaultDSOperation(AppBase.java:721)
                          	at com.isomorphic.application.AppBase.executeAppOperation(AppBase.java:658)
                          	at com.isomorphic.application.AppBase.execute(AppBase.java:491)
                          	at com.isomorphic.datasource.DSRequest.execute(DSRequest.java:1714)
                          	at com.isomorphic.servlet.IDACall.handleDSRequest(IDACall.java:199)
                          	at com.isomorphic.servlet.IDACall.processRPCTransaction(IDACall.java:156)
                          	at com.isomorphic.servlet.IDACall.processRequest(IDACall.java:121)
                          	at com.isomorphic.servlet.IDACall.doPost(IDACall.java:73)
                          	at javax.servlet.http.HttpServlet.service(HttpServlet.java:637)
                          	at com.isomorphic.servlet.BaseServlet.service(BaseServlet.java:152)
                          	at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
                          	at org.mortbay.jetty.servlet.ServletHolder.handle(ServletHolder.java:487)
                          	at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1097)
                          	at com.isomorphic.servlet.CompressionFilter.doFilter(CompressionFilter.java:259)
                          	at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1088)
                          	at org.mortbay.jetty.servlet.ServletHandler.handle(ServletHandler.java:360)
                          	at org.mortbay.jetty.security.SecurityHandler.handle(SecurityHandler.java:216)
                          	at org.mortbay.jetty.servlet.SessionHandler.handle(SessionHandler.java:181)
                          	at org.mortbay.jetty.handler.ContextHandler.handle(ContextHandler.java:729)
                          	at org.mortbay.jetty.webapp.WebAppContext.handle(WebAppContext.java:405)
                          	at org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:152)
                          	at org.mortbay.jetty.handler.RequestLogHandler.handle(RequestLogHandler.java:49)
                          	at org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:152)
                          	at org.mortbay.jetty.Server.handle(Server.java:324)
                          	at org.mortbay.jetty.HttpConnection.handleRequest(HttpConnection.java:505)
                          	at org.mortbay.jetty.HttpConnection$RequestHandler.content(HttpConnection.java:843)
                          	at org.mortbay.jetty.HttpParser.parseNext(HttpParser.java:647)
                          	at org.mortbay.jetty.HttpParser.parseAvailable(HttpParser.java:211)
                          	at org.mortbay.jetty.HttpConnection.handle(HttpConnection.java:380)
                          	at org.mortbay.io.nio.SelectChannelEndPoint.run(SelectChannelEndPoint.java:395)
                          	at org.mortbay.thread.QueuedThreadPool$PoolThread.run(QueuedThreadPool.java:488)

                          Comment


                            #28
                            Did you remove the setting sqlStorageStrategy="integer" when you grabbed the new build? That would explain both why you're not getting the fix for selects an why you're getting this error.

                            Comment


                              #29
                              The field setting is
                              Code:
                              <field name="enabled" type="boolean"/>
                              The read of the value seems OK. That is, it shows with the right value on screen. The field is defined as....
                              Code:
                                    BooleanItem enabledFld = new BooleanItem("enabled");
                              ... and it shows a checked or un-checked box as expected.

                              Comment

                              Working...
                              X