Announcement

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

    DataSource.getFileURL problem

    SmartGWT: v8.2p_2012-10-04/PowerEdition Deployment (built 2012-10-04)
    Browser: FF 15, Chrome 22

    Scenario: I'm loading up images from MySQL into an Img using SQLDataSource:
    Code:
    <DataSource
    	ID="customer_photo"
    	serverType="sql"
    	tableName="customer_photo"
    	autoDeriveSchema="true">
    		
    	<fields>
    		<field name="photo" type="imageFile"/>
    	</fields>
     
    	<operationBindings>
    		<!-- always get the newest photo -->
    		<operationBinding operationType="fetch">
    			<orderClause>photo_date DESC LIMIT 1</orderClause>
    		</operationBinding>
    	</operationBindings>
    	
    </DataSource>
    Here is the snippet of code where I call getFileURL. The customer_id is a FK in the customer_photo table. So I do a fetch on the customer_photo DataSource to retrieve the actual record (the record is returned correctly, without the binary "photo" field)
    I have also tried calling getFileURL with a manually crafted record containing a test customer_photo PK.
    Code:
    Criteria criteria = new Criteria();
    criteria.addCriteria("customer_id", customerId);
    photoDetailsForm.fetchData(criteria, new DSCallback() {
    	@Override
    	public void execute(DSResponse response, Object rawData, DSRequest request) {
    		Record record = response.getData()[0];
    		String url = customerPhotoDS.getFileURL(record, "photo");
    		photo.setSrc(url);
    	}
    });
    Here is my stacktrace on the getFileURL line:
    Code:
    23:07:22.742 [ERROR] [xxx] Uncaught exception escaped
    com.google.gwt.core.client.JavaScriptException: (InternalError): too much recursion
        at com.google.gwt.dev.shell.BrowserChannelServer.invokeJavascript(BrowserChannelServer.java:248)
        at com.google.gwt.dev.shell.ModuleSpaceOOPHM.doInvoke(ModuleSpaceOOPHM.java:136)
        at com.google.gwt.dev.shell.ModuleSpace.invokeNative(ModuleSpace.java:561)
        at com.google.gwt.dev.shell.ModuleSpace.invokeNativeObject(ModuleSpace.java:269)
        at com.google.gwt.dev.shell.JavaScriptHost.invokeNativeObject(JavaScriptHost.java:91)
        at com.google.gwt.core.client.impl.Impl.apply(Impl.java)
        at com.google.gwt.core.client.impl.Impl.entry0(Impl.java:213)
        at sun.reflect.GeneratedMethodAccessor42.invoke(Unknown Source)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
        at java.lang.reflect.Method.invoke(Unknown Source)
        at com.google.gwt.dev.shell.MethodAdaptor.invoke(MethodAdaptor.java:103)
        at com.google.gwt.dev.shell.MethodDispatch.invoke(MethodDispatch.java:71)
        at com.google.gwt.dev.shell.OophmSessionHandler.invoke(OophmSessionHandler.java:172)
        at com.google.gwt.dev.shell.BrowserChannelServer.reactToMessagesWhileWaitingForReturn(BrowserChannelServer.java:337)
        at com.google.gwt.dev.shell.BrowserChannelServer.invokeJavascript(BrowserChannelServer.java:218)
        at com.google.gwt.dev.shell.ModuleSpaceOOPHM.doInvoke(ModuleSpaceOOPHM.java:136)
        at com.google.gwt.dev.shell.ModuleSpace.invokeNative(ModuleSpace.java:561)
        at com.google.gwt.dev.shell.ModuleSpace.invokeNativeVoid(ModuleSpace.java:289)
        at com.google.gwt.dev.shell.JavaScriptHost.invokeNativeVoid(JavaScriptHost.java:107)
        at com.google.gwt.user.client.Window.alert(Window.java)
        at com.smartgwt.client.SmartGwtEntryPoint$1.onUncaughtException(SmartGwtEntryPoint.java:249)
        at com.google.gwt.core.client.impl.Impl.entry0(Impl.java:215)
        at sun.reflect.GeneratedMethodAccessor42.invoke(Unknown Source)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
        at java.lang.reflect.Method.invoke(Unknown Source)
        at com.google.gwt.dev.shell.MethodAdaptor.invoke(MethodAdaptor.java:103)
        at com.google.gwt.dev.shell.MethodDispatch.invoke(MethodDispatch.java:71)
        at com.google.gwt.dev.shell.OophmSessionHandler.invoke(OophmSessionHandler.java:172)
        at com.google.gwt.dev.shell.BrowserChannelServer.reactToMessages(BrowserChannelServer.java:292)
        at com.google.gwt.dev.shell.BrowserChannelServer.processConnection(BrowserChannelServer.java:546)
        at com.google.gwt.dev.shell.BrowserChannelServer.run(BrowserChannelServer.java:363)
        at java.lang.Thread.run(Unknown Source)
    Notes:

    1) I know that the data in the DB is correct as I can use ViewFileItem to load the image up correctly.

    2) The exception occurs at the getFileURL line, only in development mode. This appears to work fine in compiled mode.

    3) I know the usual route is to have a standalone example, but I'm hoping that this is something where I might just be misusing getFileURL.

    4) I did not see anything of interest in the developer console.


    Any pointers on something I could try?

    #2
    We would normally tell you to look at the instructions in the FAQ about what to do whenever you encounter a JavaScript error, but that requires compiled mode...

    Since this is basically a "fake" bug introduced by some kind of internal GWT problem, and won't affect your end users, you may as well ignore it. Or, if you really care about it, try some other versions of GWT to see if they've resolved it.

    Also note that problems in Chrome in specifically development mode are expected due to GWT bugs in this browser - see FAQ on that.

    Comment


      #3
      Do you have more details on how getFileURL works?

      Apologies, I believe I was incorrect when I said that it was working in compiled mode. What I saw was that the same photo was being returned every single time - it was the newest photo in the database, so this seemed to be the culprit:
      Code:
      <operationBindings>
      	<operationBinding operationType="fetch">
      		<orderClause>photo_date DESC LIMIT 1</orderClause>
      	</operationBinding>	
      </operationBindings>
      I had originally included this for the purpose of returning the newest photo for a given customer.

      I removed this entire operationBinding - which sort of made sense, if I was passing this to DataSource.getFileURL:
      Code:
      Record record = new Record();
      record.setAttribute("id", "1477");      // for testing
      String url = DataSource.get("customer_photo").getFileURL(record, "photo");
      I would expect getFileURL to retrieve the URL field "photo" of the record (which contains the PK). However what I'm seeing in the logs was from the above snippet is:

      Code:
      === 2012-10-05 00:34:35,417 [l0-0] DEBUG RPCManager - Request #1 (DSRequest) payload: {
          criteria:{
              download_fieldname:"photo"
          },
          operationConfig:{
              dataSource:"customer_photo",
              operationType:"viewFile"
          },
          appID:"builtinApplication",
          operation:"customer_photo_viewFile",
          oldValues:{
              download_fieldname:"photo"
          }
      }
      === 2012-10-05 00:34:35,417 [l0-0] INFO  IDACall - Performing 1 operation(s)
      === 2012-10-05 00:34:35,417 [l0-0] DEBUG AppBase - [builtinApplication.customer_photo_viewFile] No userTypes defined, allowing anyone access to all operations for this application
      === 2012-10-05 00:34:35,418 [l0-0] DEBUG AppBase - [builtinApplication.customer_photo_viewFile] No public zero-argument method named '_customer_photo_viewFile' found, performing generic datasource operation
      === 2012-10-05 00:34:35,419 [l0-0] DEBUG AppBase - [builtinApplication.customer_photo_viewFile, builtinApplication.null] No userTypes defined, allowing anyone access to all operations for this application
      === 2012-10-05 00:34:35,419 [l0-0] DEBUG AppBase - [builtinApplication.customer_photo_viewFile, builtinApplication.null] No public zero-argument method named '_null' found, performing generic datasource operation
      === 2012-10-05 00:34:35,419 [l0-0] INFO  SQLDataSource - [builtinApplication.customer_photo_viewFile, builtinApplication.null] Performing fetch operation with
      	criteria: {download_fieldname:"photo"}	values: {download_fieldname:"photo"}
      === 2012-10-05 00:34:35,419 [l0-0] INFO  SQLDataSource - [builtinApplication.customer_photo_viewFile, builtinApplication.null] derived query: SELECT $defaultSelectClause FROM $defaultTableClause WHERE $defaultWhereClause
      === 2012-10-05 00:34:35,420 [l0-0] INFO  SQLDataSource - [builtinApplication.customer_photo_viewFile, builtinApplication.null] Executing SQL query on 'xxx': SELECT customer_photo.customer_id, customer_photo.id, customer_photo.photo, customer_photo.photo_date, customer_photo.photo_date_created, customer_photo.photo_filename, customer_photo.photo_filesize FROM customer_photo WHERE ('1'='1')
      === 2012-10-05 00:34:35,420 [l0-0] DEBUG PoolableSQLConnectionFactory - [builtinApplication.customer_photo_viewFile, builtinApplication.null] DriverManager fetching connection for xxx via jdbc url jdbc:mysql://
      === 2012-10-05 00:34:35,420 [l0-0] DEBUG PoolableSQLConnectionFactory - [builtinApplication.customer_photo_viewFile, builtinApplication.null] Passing JDBC URL only to getConnection
      === 2012-10-05 00:34:35,447 [l0-0] DEBUG PoolableSQLConnectionFactory - [builtinApplication.customer_photo_viewFile, builtinApplication.null] Returning pooled Connection
      === 2012-10-05 00:34:35,449 [l0-0] DEBUG SQLTransaction - [builtinApplication.customer_photo_viewFile, builtinApplication.null] Started new xxx transaction "9609748"
      === 2012-10-05 00:34:35,449 [l0-0] INFO  SQLDriver - [builtinApplication.customer_photo_viewFile, builtinApplication.null] Executing SQL query on 'xxx': SELECT customer_photo.customer_id, customer_photo.id, customer_photo.photo, customer_photo.photo_date, customer_photo.photo_date_created, customer_photo.photo_filename, customer_photo.photo_filesize FROM customer_photo WHERE ('1'='1')
      === 2012-10-05 00:35:16,311 [l0-0] INFO  DSResponse - [builtinApplication.customer_photo_viewFile, builtinApplication.null] DSResponse: List with 1089 items
      === 2012-10-05 00:35:16,312 [l0-0] WARN  RequestContext - dsRequest.execute() failed: 
      java.lang.Exception: Fetched multiple results when trying single
      	at com.isomorphic.datasource.DataSource.forceSingle(DataSource.java:2591)
      	at com.isomorphic.sql.SQLDataSource.executeDownload(SQLDataSource.java:318)
      	at com.isomorphic.datasource.DataSource.execute(DataSource.java:1301)
      	at com.isomorphic.application.AppBase.executeDefaultDSOperation(AppBase.java:725)
      	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:1954)
      	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.doGet(IDACall.java:81)
      	at javax.servlet.http.HttpServlet.service(HttpServlet.java:617)
      	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.handle(ServletHandler.java:362)
      	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.headerComplete(HttpConnection.java:829)
      	at org.mortbay.jetty.HttpParser.parseNext(HttpParser.java:513)
      	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)
      === 2012-10-05 00:35:16,314 [l0-0] WARN  RPCManager - dsResponse.getData().get("photo") returned null  when we were expecting an InputStream. Can't continue.
      === 2012-10-05 00:35:16,314 [l0-0] DEBUG SQLTransaction - Ending xxx transaction "9609748"
      Note that I only see this in compiled mode, in dev mode I get the original "too much recursion error"

      So if my guess is correct, it would seem from the SQL that's being generated, it's not taking into account the PK getFileURL is being given - I only thought this worked because my DS did a LIMIT 1 and culled the list of all photos down to the single newest one.

      I hope this is only happening because I'm using getFileURL incorrectly...
      Last edited by sunnyl; 4 Oct 2012, 06:51.

      Comment


        #4
        I believe I've found the source of the issue.

        It looks like there's a difference in calling:
        Code:
        String url = customerPhotoDS.getFileURL(record);
        And:
        Code:
        String url = customerPhotoDS.getFileURL(record, "photo");
        According to the javadoc, the second parameter should be the name of the binary field, and if not specified the first binary field is used.

        The former generates this DSRequest as seen on developer console (works on both dev and compiled):
        Code:
        {
            "dataSource":"customer_photo", 
            "operationType":"viewFile", 
            "data":{
                "id":"1075", 
                "download_fieldname":"photo", 
                "download_filename":null
            }, 
            "callback":null, 
            "showPrompt":false, 
            "oldValues":{
                "id":"1075", 
                "download_fieldname":"photo", 
                "download_filename":null
            }, 
            "requestId":"customer_photo$6277"
        }
        We can see that "id" is correctly specified.

        However, in the latter code produces (which only works in compiled mode, and has "too much recursion" in dev mode):
        Code:
        {
            "dataSource":"customer_photo", 
            "operationType":"viewFile", 
            "data":{
                "download_fieldname":"photo", 
                "download_filename":null
            }, 
            "callback":null, 
            "showPrompt":false, 
            "oldValues":{
                "download_fieldname":"photo", 
                "download_filename":null
            }, 
            "requestId":"customer_photo$6276"
        }
        This is fine for me so far, but later on down the track I will be having two images in the same record, and I will need to specify which field goes to which Img.

        Isomorphic: are you able to confirm this is indeed an issue?

        Comment

        Working...
        X