Announcement

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

    LookupStyle attribute with session scope

    Hi,

    We build a prototype based on SmartGWT as part of a study (replacing our Swing GUI with an AJAX framework based one) and we encountered this problem: the custom datasource has a reference to a Stateful Bean containing the data so this datasource must have only just one instance per session.

    What I've found in the documentation seems to be perfect:
    http://www.smartclient.com/smartgwtee/javadoc/com/smartgwt/client/docs/serverds/ServerObject.html#lookupStyle

    " "attribute": The instance on which the DMI method is to be invoked is looked up in the scope defined by attributeScope via the attribute name specified in attributeName. "

    So I set the lookupStyle parameter to "attribute" plus added the attributeName and set attributeScope to "session".

    When i try this in Jetty, the custom datasource is created many times per user. What configuration parameter do I miss then or what kind of datasource lookup shall I use?
    Thank you for the help!

    Regards,
    Robert

    SmartGWT version: 2.5
    SmartClient Version: SC_SNAPSHOT-2011-08-02/EVAL Deployment
    browser(s) and version(s) involved: IE 8.0.6001.18702

    Datasource xml:
    Code:
    <DataSource ID="ScheduleChangeDatasource" attributeName="IMBackendSessionBean"
    	lookupStyle="attribute" attributeScope="session"
    	serverConstructor="com.lsy.cosma.smartclient.server.ScheduleChangeDatasource">
    	<fields>
    		<field name="scheduleChangeId" type="sequence" primaryKey="true"
    			hidden="true" />
    		<field name="rawinputKey" type="integer" hidden="true" />
    		<field name="applied" type="boolean" hidden="true" />		
    		<field name="details" type="text" hidden="true" length="65535"/>
    		<field name="actionCode" title="ActionCode" type="text" length="5"
    			required="true" />
    		<field name="airlineDesignator" title="Airline Designator" type="text"
    			length="8" required="true" />
    		<field name="flightNumber" title="Flight No." type="integer"
    			required="true" />
    		<field name="startDate" title="From" type="text" length="7" />
    		<field name="endDate" title="To" type="text" length="7" />
    		<field name="daysOfOp" title="DaysOfOperation" type="text"
    			length="5" required="true" />
    		<field name="adhoc" title="Adhoc" type="boolean" required="true" />		
    	</fields>
    </DataSource>

    Ant task:
    Code:
      <target name="hosted" depends="cosma-libs, javac" description="Run hosted mode">
        <java failonerror="true" fork="true" classname="com.google.gwt.dev.HostedMode">
          <classpath>
            <pathelement location="src"/>
            <path refid="project.class.path"/>
          </classpath>
          <jvmarg value="-Xmx256M"/>
          <jvmarg value="-Dproto.test=false"/>
          <jvmarg value="-DwlUrl=t3://vmh-scappi02.schedconnect.fra.dlh.de:7021"/>
          <jvmarg value="-Djava.naming.factory.initial=weblogic.jndi.WLInitialContextFactory"/>
    	  <jvmarg value="${macJvmArgs}"/>
          <arg value="-startupUrl"/>
          <arg value="SmartClient.html"/>
          <!-- Additional arguments like -style PRETTY or -logLevel DEBUG -->
          <arg value="com.lsy.cosma.smartclient.SmartClient"/>
        </java>
      </target>
    Datasource init in client:
    Code:
             DataSource ds = DataSource.getDataSource("ScheduleChangeDatasource");
             Criteria criteria = new Criteria();
             criteria.setAttribute("rawinputKey", new Long(rawInputKey));
             criteria.setAttribute("applied", Boolean.valueOf(applied));
             scheduleChangeGrid.setDataSource(ds);
             scheduleChangeGrid.fetchData(criteria);
    Datasource would be reused here when a row is clicked in the grid, by default the "details" column data is not downloaded:

    Code:
          listGrid.addCellClickHandler(new CellClickHandler()
          {
             @Override
             public void onCellClick(CellClickEvent event)
             {
                System.out.println("Click callback invoked!");
                DataSource ds = DataSource.getDataSource("ScheduleChangeDatasource");
                Criteria criteria = new Criteria();
                criteria.setAttribute("rawinputKey", new Long(rawInputKey));
                criteria.setAttribute("applied", Boolean.valueOf(applied));
                criteria.setAttribute("rowId", event.getRowNum());            
                ds.fetchData(criteria, new DSCallback()
                {
                   @Override
                   public void execute(DSResponse response, Object rawData, DSRequest request)
                   {
                      System.out.println("Datasource callback for one row details");
                      String html = "";
                      if (response.getData() != null && response.getData().length == 1)
                      {
                         html = response.getData()[0].getAttributeAsString("details");
                      }
                      System.out.println("Click callback invoked. html details: " + html);                  
    
                      changeDetails.setContents(html);
                   }
                });
             }
          });

    #2
    Multiple instances of the same DataSources are created server-side, and pooled - each can be used only by one thread at a time.

    If you have a single stateful session bean and you want to keep that architecture, just have each DataSource instance look it up and use the same one.

    However note, generally the best architecture is to have no state on the application server (SmartGWT requires none), so completely aside from SmartGWT you may want to rethink your architecture here.

    As far as the "details" field, there's something wrong with your code on IMBackendSessionBean for the "fetch" operation. Either you are returning data/beans with no "details" value, or the bean has no getDetails/setDetails APIs that would allow "details" to be detected as a Java Bean property.

    Comment


      #3
      Thank you very much for your quick response!

      The architecture is as it is, we would like to discover how SmartGWT can help us to create a GUI that can communicate with even our current architecture as we can not replace many parts of our system in one step, it's pretty big.

      To distill the question: I thought I would have been able to use the same instance of the datasource from the client side with the DataSource.getDataSource("ID") lookup if the datasource was configured as I described.

      So if I understood your answer:
      - I shall look up the datasource in the client with DataSource.getDataSource("ID") and store the reference
      - next time when I need to use the same datasource then instead of looking up again I shall use the previously looked up reference

      I'm still interested in then what the lookupStyle=attribute is good for if not for having only one datasource instance belonging to one user session or one application.

      Comment


        #4
        Client-side there is only one DataSource instance per DataSource ID (client-side is single threaded).

        Server-side there is a pool. Server-side, you should not be storing references to DataSources as you will then be holding onto a DataSource that has been returned to the pool, hence you'll end up with 2 threads in one DataSource instance, which is not allowed.

        Reread what we said:

        If you have a single stateful session bean and you want to keep that architecture, just have each DataSource instance look it up and use the same one.
        "same one" meant same stateful bean.

        Comment

        Working...
        X