Announcement

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

    How do I set a bean-backed attribute via ListGrid.setEditValue?

    SmartClient Version: v8.3p_2013-08-06/Pro Deployment (built 2013-08-06)

    Google Chrome Version 40.0.2214.93 (64-bit) (Mac OS X)

    I have two ListGrids. The first is for a "batch", and the second is for a list of "payments" associated with the selected "batch".

    The "batches" are stored in a table (payment_batch). The payments are stored in a table (payments). There is a linker table (payment_batch_to_payments) that links them together. The data sources are using Hibernate.

    Payment Batch:
    Code:
    <DataSource ID="DAOPaymentBatchDS" serverType="hibernate" beanClassName="com.legaledge.maestro.server.model.report.DAOPaymentBatch" dropExtraFields="true">
    	<fields>
    		<field name="id" autoGenerated="true" hidden="true" primaryKey="true"/>
    		<field name="identifierId" type="long" hidden="true"/>
    		<field name="relationshipId" type="long" hidden="true"/>
    		<field name="startTime" title="Start Time" type="time" required="false" useTextField="true" >
    		</field>
    		<field name="startDate" title="Start Date" type="date" required="false" useTextField="true" >
    		</field>
    		<field name="status" title="Status" type="text" required="false" >
    		</field>
    		<field name="description" title="Description" type="text" required="false" >
    		</field>
    		<field name="batchNumber" title="Batch Number" type="text" required="true" >
    		</field>
    		<field name="endDate" title="End Date" type="date" required="false" useTextField="true" >
    		</field>
    		<field name="endTime" title="End Time" type="time" required="false" useTextField="true" >
    		</field>
    		<field name="outcomeType" title="Outcome Type" type="text" required="false" >
    		</field>
    		<field name="completionDate" title="Completion Date" type="date" required="false" useTextField="true" >
    		</field>
    		
    		<field name="DAOPaymentBatchToPaymentses" hidden="false" multiple="true" type="DAOPaymentBatchToPaymentsDS"  />
    		<field name="DAOPayments" hidden="false" multiple="true" type="DAOPaymentsDS" />
    	</fields>
    </DataSource>
    Payments:

    Code:
    <DataSource ID="DAOPaymentsDS" serverType="hibernate" beanClassName="com.legaledge.maestro.server.model.report.DAOPayments" dropExtraFields="true">
    	<fields>
    		<field name="id" autoGenerated="true" hidden="true" primaryKey="true"/>
    		<field name="identifierId" type="long" hidden="true"/>
    		<field name="relationshipId" type="long" hidden="true"/>
    		<field name="amount" title="Amount" type="text" required="false" >
    		</field>
    		<field name="startDate" title="Start Date" type="date" required="false" useTextField="true" >
    		</field>
    		<field name="paid" title="Paid" type="boolean" required="false" >
    		</field>
    		<field name="tender" title="Tender" type="text" required="false" editorType="select" optionDataSource="picklistHBValue" displayField="stringValue" valueField="stringValue" >
    			<pickListCriteria>
    				<name>PaymentsTender</name>
    			</pickListCriteria>
    		</field>
    		<field name="amountPaid" title="Amount Paid" type="text" required="false" >
    		</field>
    		<field name="recordBy" title="Record By" type="text" required="false" editorType="select" optionDataSource="picklistHBValue" displayField="stringValue" valueField="stringValue" >
    			<pickListCriteria>
    				<name>PaymentsRecordBy</name>
    			</pickListCriteria>
    		</field>
    		<field name="primaryReferenceNumber" title="Primary Reference Number" type="text" required="false" >
    		</field>
    		<field name="paidBy" title="Paid By" type="text" required="false" >
    		</field>
    		
    		<field name="DAOPaymentBatchToPaymentsesID" title="Rel ID" type="long" required="false" valueXPath="DAOPaymentBatchToPaymentses/id"/>
    		<field name="DAOPaymentBatchToPaymentsesPrimary" title="Primary" type="boolean" required="false" valueXPath="DAOPaymentBatchToPaymentses/primary"/>
    			
    	</fields>
    </DataSource>
    Payment Batch To Payments:

    Code:
    <DataSource ID="DAOPaymentBatchToPaymentsDS" serverType="hibernate" beanClassName="com.legaledge.maestro.server.model.report.DAOPaymentBatchToPayments" dropExtraFields="true">
    	<fields>
    		<field name="id" autoGenerated="true" hidden="true" primaryKey="true"/>
    		<field name="identifierId" type="long" hidden="true"/>
    		<field name="relationshipId" type="long" hidden="true"/>
    		<field name="primary" title="Primary" type="boolean" required="false"/>
    		
    		<field name="paymentsAmount" title="Amount" type="text" required="false" valueXPath="DAOPayments/amount"/>
    		<field name="paymentsAmountPaid" title="Amount Paid" type="text" required="false" valueXPath="DAOPayments/amountPaid"/>
    		<field name="paymentsStartDate" title="Start Date" type="date" required="false" useTextField="true" valueXPath="DAOPayments/startDate"/>
    		<field name="paymentsPaid" title="Paid" type="boolean" required="false" valueXPath="DAOPayments/paid"/>
    		<field name="paymentsTender" title="Tender" type="text" required="false" valueXPath="DAOPayments/DAOPicklistValueByTender/stringValue"/>
    		<field name="paymentsRecordBy" title="Record By" type="text" required="false" valueXPath="DAOPayments/DAOPicklistValueByRecordBy/stringValue"/>
    		<field name="paymentsPrimaryReferenceNumber" title="Primary Reference Number" type="text" required="false" valueXPath="DAOPayments/primaryReferenceNumber"/>
    		<field name="paymentsPaidBy" title="Paid By" type="text" required="false" valueXPath="DAOPayments/paidBy"/>
    		
    		<field name="DAOPayments" />
    		<field name="DAOPaymentBatch" />
    		
    		<field name="DAOPaymentID" valueXPath="DAOPayments/id"/>
    		<field name="DAOPaymentBatchID" valueXPath="DAOPaymentBatch/id"/>
    		
    	</fields>
    </DataSource>
    Here's how I set up the grid of Batches:

    Code:
    		final ListGrid paymentBatchesList = new ListGrid();
    		paymentBatchesList.setDataSource(Utils.getDS("DAOPaymentBatchDS"));
    		paymentBatchesList.setAutoFetchData(true);
    		paymentBatchesList.setAlternateRecordStyles(true);
    		paymentBatchesList.setShowFilterEditor(true);
    		paymentBatchesList.setCanRemoveRecords(true);
    		paymentBatchesList.setCanEdit(true);
    		IButton newBatchButton = new IButton("Add New Payment Batch");
    		newBatchButton.setWidth(250);
    		newBatchButton.addClickHandler(new ClickHandler() {
    			public void onClick(ClickEvent event) {
    				paymentBatchesList.startEditingNew();
    			}
    		});
    And I use DAOPaymentBatchToPaymentsDS as the datasource to drive the list of payments. This datasource has flattened elements from the payments table, using valueXPath:

    Code:
    		final ListGrid paymentBatchToPaymentsList = new ListGrid();
    		paymentBatchToPaymentsList.setDataSource(Utils.getDS("DAOPaymentBatchToPaymentsDS"));
    		paymentBatchToPaymentsList.setCanRemoveRecords(true);
    		paymentBatchToPaymentsList.setCanEdit(true);
    		
    		IButton newPaymentButton = new IButton("Add New Payment");
    		newPaymentButton.addClickHandler(new ClickHandler() {
    			public void onClick(ClickEvent event) {
    				paymentBatchToPaymentsList.startEditingNew();  // add a new payment & rel
    				int len = paymentBatchToPaymentsList.getRecords().length;
    				paymentBatchToPaymentsList.setEditValue(len, "DAOPaymentBatch", paymentBatchesList.getSelectedRecord());
    			}
    		});
    When a user adds a new payment, I want the payment record to save first. Then I want the payment_batch_to_payment record to link the payment to the batch, and then to save.

    Upon clicking the New button, I need to tell the 2nd datasource which batch is selected. Then the new payment information will get associated with the correct batch. But when I call setEditValue with the entire Record (corresponding to the selected payment batch), the server interprets it as a String. This fails, and prevents Hibernate from creating the payment_batch_to_payment record since one side of the relationship is missing.

    Here's the error:
    Code:
    2015-01-28 13:46:59,159 INFO  [STDOUT] === 2015-01-28 13:46:59,159 [80-1] WARN  DataSource - [builtinApplication.DAOPaymentBatchToPaymentsDS_add] Exception trying to set properties for datasource: DAOPa
    ymentBatchToPaymentsDS from: {DAOPaymentBatch={DAOPaymentBatchToPaymentses=[], DAOPayments=[], startDate=Wed Jan 14 00:00:00 EST 2015, status=asdf, endDate=null, endTime=null, outcomeType=null, startTim
    e=null, id=0, batchNumber=12341aAsdfadg4dgfg, description=dasfadsf, completionDate=null, _selection_9=true}} to: com.legaledge.maestro.server.model.report.DAOPaymentBatchToPayments@4c21261c. Actual erro
    r: java.lang.IllegalArgumentException: Can't convert value of type java.lang.String to target type com.legaledge.maestro.server.model.report.DAOPaymentBatch
    2015-01-28 13:46:59,159 INFO  [STDOUT] java.lang.IllegalArgumentException: Can't convert value of type java.lang.String to target type com.legaledge.maestro.server.model.report.DAOPaymentBatch
    2015-01-28 13:46:59,159 INFO  [STDOUT]  at com.isomorphic.util.DataTools.convertType(DataTools.java:3466)
    2015-01-28 13:46:59,159 INFO  [STDOUT]  at com.isomorphic.util.DataTools.createSetterArgument(DataTools.java:3270)
    2015-01-28 13:46:59,159 INFO  [STDOUT]  at com.isomorphic.util.DataTools.coerceProperty(DataTools.java:3208)
    2015-01-28 13:46:59,159 INFO  [STDOUT]  at com.isomorphic.util.DataTools.setProperties(DataTools.java:2993)
    2015-01-28 13:46:59,159 INFO  [STDOUT]  at com.isomorphic.datasource.DataSource.setProperties(DataSource.java:1720)
    2015-01-28 13:46:59,159 INFO  [STDOUT]  at com.isomorphic.datasource.DataSource.setProperties(DataSource.java:1584)
    2015-01-28 13:46:59,159 INFO  [STDOUT]  at com.isomorphic.hibernate.HibernateDataSource.processRequest(HibernateDataSource.java:1421)
    2015-01-28 13:46:59,159 INFO  [STDOUT]  at com.isomorphic.hibernate.HibernateDataSource.executeAdd(HibernateDataSource.java:825)
    2015-01-28 13:46:59,159 INFO  [STDOUT]  at com.isomorphic.datasource.DataSource.execute(DataSource.java:1370)
    2015-01-28 13:46:59,159 INFO  [STDOUT]  at com.isomorphic.application.AppBase.executeDefaultDSOperation(AppBase.java:723)
    2015-01-28 13:46:59,159 INFO  [STDOUT]  at com.isomorphic.application.AppBase.executeAppOperation(AppBase.java:658)
    2015-01-28 13:46:59,159 INFO  [STDOUT]  at com.isomorphic.application.AppBase.execute(AppBase.java:491)
    2015-01-28 13:46:59,159 INFO  [STDOUT]  at com.isomorphic.datasource.DSRequest.execute(DSRequest.java:2044)
    2015-01-28 13:46:59,159 INFO  [STDOUT]  at com.isomorphic.servlet.IDACall.handleDSRequest(IDACall.java:216)
    2015-01-28 13:46:59,159 INFO  [STDOUT]  at com.isomorphic.servlet.IDACall.processRPCTransaction(IDACall.java:173)
    2015-01-28 13:46:59,159 INFO  [STDOUT]  at com.isomorphic.servlet.IDACall.processRequest(IDACall.java:138)
    2015-01-28 13:46:59,159 INFO  [STDOUT]  at com.isomorphic.servlet.IDACall.doPost(IDACall.java:74)
    How do I tell that second ListGrid that my value for the DAOPaymentBatch column should be an instance of the DAOPaymentBatch bean instead of a literal String?

    Here is the Hibernate mapping for the bean that represents the payment batch to payment relationship:

    Code:
    <?xml version="1.0"?>
    <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
    "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
    <!-- Generated Jan 22, 2015 4:00:20 PM by Hibernate Tools 3.4.0.CR1 -->
    <hibernate-mapping>
        <class name="com.legaledge.maestro.server.model.report.DAOPaymentBatchToPayments" table="payment_batch_to_payments_" schema="report">
            <id name="id" type="java.lang.Long">
                <column name="id" />
                <generator class="com.legaledge.maestro.server.dao.id.SQLServerIdGenerator">
                    <param name="table">dbuid_sequence</param>
                </generator>
            </id>
            <many-to-one name="DAOPayments" class="com.legaledge.maestro.server.model.report.DAOPayments" fetch="select">
                <column name="t$payments_" />
            </many-to-one>
            <many-to-one name="DAOPaymentBatch" class="com.legaledge.maestro.server.model.report.DAOPaymentBatch" fetch="select">
                <column name="s$payment_batch_" />
            </many-to-one>
            <property name="createdTime" type="timestamp">
                <column name="created_time" length="23" />
            </property>
            <property name="updatedTime" type="timestamp">
                <column name="updated_time" length="23" />
            </property>
            <property name="isPrimary" type="java.lang.Boolean">
                <column name="is_primary_" />
            </property>
            <property name="name" type="string">
                <column name="name_" />
            </property>
        </class>
    </hibernate-mapping>
    Here is some more context from the log leading up to the exception. The DSRequest payload seems to have the correct, structured values corresponding to my server-side beans. What do I need to do to tell SmartGWT to interpret those values as an instance of the DAOPaymentBatch bean?

    Code:
    2015-01-28 13:46:59,157 INFO  [STDOUT] === 2015-01-28 13:46:59,157 [80-1] DEBUG RPCManager - Request #1 (DSRequest) payload: {
        values:{
            DAOPaymentBatch:{
                DAOPaymentBatchToPaymentses:[
                ],
                DAOPayments:[
                ],
                startDate:new Date(1421211600000),
                status:"asdf",
                endDate:null,
                endTime:null,
                outcomeType:null,
                startTime:null,
                id:0,
                batchNumber:"12341aAsdfadg4dgfg",
                description:"dasfadsf",
                completionDate:null,
                _selection_9:true
            },
            paymentsAmount:"666",
            paymentsAmountPaid:"123"
        },
        operationConfig:{
            dataSource:"DAOPaymentBatchToPaymentsDS",
            operationType:"add"
        },
        componentId:"isc_ListGrid_1",
        appID:"builtinApplication",
        operation:"DAOPaymentBatchToPaymentsDS_add",
        oldValues:{
            DAOPaymentBatch:{
                DAOPaymentBatchToPaymentses:[
                ],
                DAOPayments:[
                ],
                startDate:new Date(1421211600000),
                status:"asdf",
                endDate:null,
                endTime:null,
                outcomeType:null,
                startTime:null,
                id:0,
                batchNumber:"12341aAsdfadg4dgfg",
                description:"dasfadsf",
                completionDate:null,
                _selection_9:true
            },
            paymentsAmount:"666",
            paymentsAmountPaid:"123"
        },
        criteria:{
        }
    }
    
    2015-01-28 13:46:59,157 INFO  [STDOUT] === 2015-01-28 13:46:59,157 [80-1] INFO  IDACall - Performing 1 operation(s)
    2015-01-28 13:46:59,157 INFO  [STDOUT] === 2015-01-28 13:46:59,157 [80-1] DEBUG DeclarativeSecurity - Processing security checks for DataSource null, field null
    2015-01-28 13:46:59,157 INFO  [STDOUT] === 2015-01-28 13:46:59,157 [80-1] DEBUG DeclarativeSecurity - DataSource DAOPaymentBatchToPaymentsDS is not in the pre-checked list, processing...
    2015-01-28 13:46:59,157 INFO  [STDOUT] === 2015-01-28 13:46:59,157 [80-1] DEBUG AppBase - [builtinApplication.DAOPaymentBatchToPaymentsDS_add] No userTypes defined, allowing anyone access to all operations for this application
    2015-01-28 13:46:59,157 INFO  [STDOUT] === 2015-01-28 13:46:59,157 [80-1] DEBUG AppBase - [builtinApplication.DAOPaymentBatchToPaymentsDS_add] No public zero-argument method named '_DAOPaymentBatchToPaymentsDS_add' found, performing generic datasource operation
    2015-01-28 13:46:59,157 INFO  [STDOUT] === 2015-01-28 13:46:59,157 [80-1] INFO  HibernateDataSource - [builtinApplication.DAOPaymentBatchToPaymentsDS_add] Performing add operation with
            criteria: {DAOPaymentBatch:{DAOPaymentBatchToPaymentses:[],DAOPayments:[],startDate:new Date(1421211600000),status:"asdf",endDate:null,endTime:null,outcomeType:null,startTime:null,id:0,batchNumber:"12341aAsdfadg4dgfg",description:"dasfadsf",completionDate:null,_selection_9:true},paymentsAmount:"666",paymentsAmountPaid:"123"}  values: {DAOPaymentBatch:"{DAOPaymentBatchToPaymentses=[], DAOPayments=[], startDate=Wed Jan 14 00:00:00 EST 2015, status=asdf, endDate=null, endTime=null, outcomeType=null, startTime=null, id=0, batchNumber=12341aAsdfadg4dgfg, description=dasfadsf, completionDate=null, _selection_9=true}",paymentsAmount:"666",paymentsAmountPaid:"123"}
    2015-01-28 13:46:59,158 DEBUG [org.hibernate.impl.SessionImpl] opened session at timestamp: 14224708191
    2015-01-28 13:46:59,158 DEBUG [org.hibernate.transaction.JDBCTransaction] begin
    2015-01-28 13:46:59,158 DEBUG [org.hibernate.jdbc.ConnectionManager] opening JDBC connection
    2015-01-28 13:46:59,158 DEBUG [org.hibernate.connection.DriverManagerConnectionProvider] total checked-out connections: 0
    2015-01-28 13:46:59,158 DEBUG [org.hibernate.connection.DriverManagerConnectionProvider] using pooled JDBC connection, pool size: 1
    2015-01-28 13:46:59,158 DEBUG [org.hibernate.transaction.JDBCTransaction] current autocommit status: false
    2015-01-28 13:46:59,158 DEBUG [org.hibernate.jdbc.JDBCContext] after transaction begin
    2015-01-28 13:46:59,158 INFO  [STDOUT] === 2015-01-28 13:46:59,158 [80-1] DEBUG HibernateTransaction - [builtinApplication.DAOPaymentBatchToPaymentsDS_add] Started new transaction "1481359656"
    2015-01-28 13:46:59,159 INFO  [STDOUT] === 2015-01-28 13:46:59,159 [80-1] WARN  DataSource - [builtinApplication.DAOPaymentBatchToPaymentsDS_add] Exception trying to set properties for datasource: DAOPaymentBatchToPaymentsDS from: {DAOPaymentBatch={DAOPaymentBatchToPaymentses=[], DAOPayments=[], startDate=Wed Jan 14 00:00:00 EST 2015, status=asdf, endDate=null, endTime=null, outcomeType=null, startTime=null, id=0, batchNumber=12341aAsdfadg4dgfg, description=dasfadsf, completionDate=null, _selection_9=true}} to: com.legaledge.maestro.server.model.report.DAOPaymentBatchToPayments@4c21261c. Actual error: java.lang.IllegalArgumentException: Can't convert value of type java.lang.String to target type com.legaledge.maestro.server.model.report.DAOPaymentBatch
    2015-01-28 13:46:59,159 INFO  [STDOUT] java.lang.IllegalArgumentException: Can't convert value of type java.lang.String to target type com.legaledge.maestro.server.model.report.DAOPaymentBatch
    2015-01-28 13:46:59,159 INFO  [STDOUT]  at com.isomorphic.util.DataTools.convertType(DataTools.java:3466)
    2015-01-28 13:46:59,159 INFO  [STDOUT]  at com.isomorphic.util.DataTools.createSetterArgument(DataTools.java:3270)
    2015-01-28 13:46:59,159 INFO  [STDOUT]  at com.isomorphic.util.DataTools.coerceProperty(DataTools.java:3208)
    2015-01-28 13:46:59,159 INFO  [STDOUT]  at com.isomorphic.util.DataTools.setProperties(DataTools.java:2993)
    2015-01-28 13:46:59,159 INFO  [STDOUT]  at com.isomorphic.datasource.DataSource.setProperties(DataSource.java:1720)
    2015-01-28 13:46:59,159 INFO  [STDOUT]  at com.isomorphic.datasource.DataSource.setProperties(DataSource.java:1584)
    2015-01-28 13:46:59,159 INFO  [STDOUT]  at com.isomorphic.hibernate.HibernateDataSource.processRequest(HibernateDataSource.java:1421)
    2015-01-28 13:46:59,159 INFO  [STDOUT]  at com.isomorphic.hibernate.HibernateDataSource.executeAdd(HibernateDataSource.java:825)
    2015-01-28 13:46:59,159 INFO  [STDOUT]  at com.isomorphic.datasource.DataSource.execute(DataSource.java:1370)
    2015-01-28 13:46:59,159 INFO  [STDOUT]  at com.isomorphic.application.AppBase.executeDefaultDSOperation(AppBase.java:723)
    2015-01-28 13:46:59,159 INFO  [STDOUT]  at com.isomorphic.application.AppBase.executeAppOperation(AppBase.java:658)
    2015-01-28 13:46:59,159 INFO  [STDOUT]  at com.isomorphic.application.AppBase.execute(AppBase.java:491)
    2015-01-28 13:46:59,159 INFO  [STDOUT]  at com.isomorphic.datasource.DSRequest.execute(DSRequest.java:2044)
    2015-01-28 13:46:59,159 INFO  [STDOUT]  at com.isomorphic.servlet.IDACall.handleDSRequest(IDACall.java:216)
    Thanks for any help, and let me know if I need to supply more details.

    #2
    Update:

    I modified the datasource for the relationship table to explicitly include the types of the participants in the relationship:

    Code:
    		<field name="DAOPayments" type="DAOPaymentsDS" hidden="true" valueXPath="DAOPayments" />
    		<field name="DAOPaymentBatch" type="DAOPaymentBatchDS" hidden="true" valueXPath="DAOPaymentBatch" />
    Now I no longer get the "Can't convert value of type java.lang.String to target type com.legaledge.maestro.server.model.report.DAOPaymentBatch" error, but the relationship is still missing the PaymentBatch instance upon save. I will look for any further mistakes on my part.

    Comment


      #3
      I have now fixed the problem. Looking at the logs, I discovered some attempts to call setters that did not exist. So I added the missing setters. Also, I found that I needed to initialize a blank Record to get the embedded Payment (within the DAOPaymentBatchToPaymentsDS datasource) recognized as a new object to be saved upon completion of list grid edits. To recap, the "Add New Payment" button handler does this:

      paymentBatchToPaymentsList.setEditValue(len, "DAOPaymentBatch", paymentBatchesList.getSelectedRecord());

      Since the DAOPaymentBatch attribute now has an explicit type of DAOPaymentBatchDS in DAOPaymentBatchToPaymentsDS, SmartGWT recognizes the passed data and properly initializes the backend bean instead of trying to coerce a String into the bean.

      To get the other side of the relationship working, I added this to the "Add New Payment" button handler:

      paymentBatchToPaymentsList.setEditValue(len, "DAOPayments", new Record());

      This seems to allow the ListGrid to pass both objects as children of the relationship object for Hibernate to persist.

      Comment

      Working...
      X