Announcement

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

    Rare stacktrace after update to 4.1

    Hi there,

    I've just updated to latest SmartGWT LGPL => SmartClient Version: v9.1p_2014-07-15/LGPL Development Only (built 2014-07-15). I'm using Firefox 26 on Windows 7 x64 with latest updates. On serverside I'm using JSON Rest webservices implemented using Jersey

    When I start the webapp, automatically a fetch is done. Always worked but after the version update Firefox freeze and I get this stacktrace in the SC debug window:

    Code:
    11:16:04.496:XRP7:INFO:RestDataSource:empresaGestoraDS:DataSource specifies jsonPrefix, but not present in response returned from server. Processing response anyway.
    11:16:04.497:XRP7:INFO:RestDataSource:empresaGestoraDS:DataSource specifies jsonSuffix, but not present in response returned from server. Processing response anyway.
    I don't use preffix / suffix in any DataSource definition. Then, the JSON response sent from server and the stacktrace

    Code:
    11:16:04.527:XRP7:DEBUG:xmlBinding:empresaGestoraDS:Raw response data: {
        "response":{
            "status":0, 
            "startRow":0, 
            "endRow":1, 
            "totalRows":1, 
            "data":[
                {
                    "id":32739, 
                    "alias":"Foo", 
                    "modoFacturacion":null, 
                    "fechaDesde":null, 
                    "observacionesPago":null, 
                    "tipoPago":null, 
                    "tipoPagoDefecto":"BarBarBar", 
                    "cantidadDias":null, 
                    "apartirDia":null, 
                    "esCliente":false, 
                    "esProveedor":false, 
                    "valoracionProveedor":"A", 
                    "observacionValoracionProveedor":null, 
                    "activo":true, 
                    "secuencia":null, 
                    "documentosIdentidad":[
                        {
                            "id":32741, 
                            "tipo":"cif", 
                            "identificador":"T000000"
                        }
                    ], 
                    "direcciones":[
                        {
                            "id":32740, 
                            "direccion":"Vía, 2", 
                            "pais":{
                                "idPais":1, 
                                "nombrePais":"España", 
                                "provincias":null
                            }, 
                            "provincia":{
                                "idProvincia":28, 
                                "nombreProvincia":"Madrid", 
                                "codigoProvincia":"28", 
                                "pais":{
                                    "idPais":1, 
                                    "nombrePais":"España", 
                                    "provincias":null
                                }, 
                                "poblaciones":null
                            }, 
                            "poblacion":{
                                "idPoblacion":16318, 
                                "nombrePoblacion":"Alcalá de Henares", 
                                "provincia":{
                                    "idProvincia":28, 
                                    "nombreProvincia":"Madrid", 
                                    "codigoProvincia":"28", 
                                    "pais":{
                                        "idPais":1, 
                                        "nombrePais":"España", 
                                        "provincias":null
                                    }, 
                                    "poblaciones":null
                                }, 
                                "codigosPostales":null
                            }, 
                            "codigoPostal":{
                                "idCodigoPostal":5871, 
                                "nombreCodigoPostal":"28805", 
                                "poblaciones":null
                            }, 
                            "esDireccionFacturacion":false
                        }
                    ], 
                    "mediosContacto":[
                        {
                            "id":32742, 
                            "medio":"FAX", 
                            "valor":"0000000"
                        }, 
                        {
                            "id":32743, 
                            "medio":"TELEFONOFIJO", 
                            "valor":"000000"
                        }
                    ], 
                    "notas":[
                    ], 
                    "cuentaFacturacion":null, 
                    "cuentaFacturacionAlt":null, 
                    "condicionesParada":[
                    ], 
                    "razonSocial":"FooBar", 
                    "logoGeneral":"x.jpg", 
                    "logoDocumentos":"y.jpg", 
                    "registroMercantil":"TestTest", 
                    "cuentasBancarias":[
                        {
                            "id":32744, 
                            "entidad":"Banco Popular", 
                            "numeroCuenta":"1234567"
                        }
                    ], 
                    "tipoMoneda":"EURO"
                }
            ], 
            "errors":null
        }
    }
    11:16:04.529:XRP7:INFO:xmlBinding:empresaGestoraDS:JSON recordXPath: '/response/data', selected: Array[1]
    11:16:04.549:XRP7:WARN:Log:TypeError: _1 is null
    Stack from error.stack:
        DataSource.validateJSONRecord() @ ns/sc/modules/ISC_DataBinding.js:601
        DataSource.validateJSONRecord() @ ns/sc/modules/ISC_DataBinding.js:604
        DataSource.validateJSONRecord() @ ns/sc/modules/ISC_DataBinding.js:604
        DataSource.validateJSONRecord() @ ns/sc/modules/ISC_DataBinding.js:604
        DataSource.recordsFromObjects() @ ns/sc/modules/ISC_DataBinding.js:600
        DataSource._handleJSONReply() @ ns/sc/modules/ISC_DataBinding.js:586
        isc.A.$379() @ ns/sc/modules/ISC_DataBinding.js:600
        [c]Class.fireCallback() @ ns/sc/modules/ISC_Core.js:259
        [c]Class.fireCallback() @ ns/sc/modules/ISC_Core.js:320
        anonymous() @ ns/sc/modules/ISC_DataBinding.js:1575
        $wnd.isc.RPCManager.fireReplyCallback() @ :262
        [c]RPCManager.fireReplyCallbacks() @ ns/sc/modules/ISC_DataBinding.js:1580
        [c]RPCManager.performOperationReply() @ ns/sc/modules/ISC_DataBinding.js:1573
        RPCManager._performTransactionReply() @ ns/sc/modules/ISC_DataBinding.js:1558
        [c]RPCManager.performTransactionReply() @ ns/sc/modules/ISC_DataBinding.js:1484
        anonymous() @ ns/sc/modules/ISC_Core.js:50
        [c]Class.fireCallback() @ ns/sc/modules/ISC_Core.js:259
        [c]Comm.performXmlTransactionReply() @ ns/sc/modules/ISC_Core.js:1084
        anonymous() @ ns/sc/modules/ISC_Core.js:50
        [c]Class.fireCallback() @ ns/sc/modules/ISC_Core.js:259
        Comm._fireXMLCallback() @ ns/sc/modules/ISC_Core.js:1067
        Comm.sendXmlHttpRequest/_12() @ ns/sc/modules/ISC_Core.js:1072
        unnamed() @ 
    
    11:16:04.558:XRP7:WARN:Log:Uncaught JavaScript exception: TypeError: _1 is null in http://127.0.0.1:8888/ns/sc/modules/ISC_DataBinding.js, line 601
    Why is this happening? This worked fine in 4.0 and earlier versions. Looking in Releases Notes I can't see any related major change in RestDataSource
    Last edited by hespresati; 15 Jul 2014, 01:43. Reason: Fixs

    #2
    jsonPrefix is on by default and we recommend using it. See the docs for why.

    Can we see the DataSource you are using to process this response? This error looks like a problem with data not matching field declarations.

    Comment


      #3
      Good morning,

      ok! I see the advantages of using json preffix / suffix. I'll see how I cant wrap the response from the existing Jersey webservices.

      The RestDataSource we are using is a hierarchical approximation. EmpresaGestoraDS inherit from ContactoDS. So from top to bottom:

      ContactoDS
      Code:
      package com.arplatia.ns.client.contacto.dataSource;
      
      import java.util.LinkedHashMap;
      
      import com.arplatia.ns.client.contacto.ContactoConstants;
      import com.arplatia.ns.client.contacto.direccion.dataSource.DireccionDS;
      import com.arplatia.ns.client.contacto.documentoIdentidad.dataSource.DocumentoIdentidadDS;
      import com.arplatia.ns.client.contacto.empresa.compRenting.condicionParada.dataSource.CondicionParadaDS;
      import com.arplatia.ns.client.contacto.medioContacto.dataSource.MedioContactoDS;
      import com.arplatia.ns.client.contacto.relacionesClienteTaller.dataSource.RelacionesClienteTallerDS;
      import com.arplatia.ns.client.nota.dataSource.NotaDS;
      import com.arplatia.ns.client.secuenciaFras.dataSource.SecuenciaFrasDS;
      import com.arplatia.ns.client.util.JSONRestDataSource;
      import com.google.gwt.core.client.GWT;
      import com.smartgwt.client.data.DataSourceField;
      import com.smartgwt.client.data.fields.DataSourceBooleanField;
      import com.smartgwt.client.data.fields.DataSourceEnumField;
      import com.smartgwt.client.data.fields.DataSourceIntegerField;
      import com.smartgwt.client.data.fields.DataSourceTextField;
      
      public class ContactoDS extends JSONRestDataSource {
      	// Locale
      	private ContactoConstants locale = GWT.create(ContactoConstants.class);
      
      	private static ContactoDS instance = null;
      
      	public static ContactoDS getInstance() {
      		if (instance == null) {
      			instance = new ContactoDS("contactoDS");
      		}
      
      		return instance;
      	}
      
      	public ContactoDS(String idDataSource) {
      		// Establecer Id del DataSource
      		setID(idDataSource);
      
      		// Operaciones CRUD del REST
      		setFetchDataURL("rest/contacto/fetch");
      		setAddDataURL("rest/contacto/add");
      		setUpdateDataURL("rest/contacto/update");
      		setRemoveDataURL("rest/contacto/remove");
      
      		// Protocolo de SmartGWT
      		setSendMetaData(true);
      		setCacheAllData(false);
      		setAutoCacheAllData(false);
      
      		// ID
      		DataSourceIntegerField id = new DataSourceIntegerField("id", locale.id());
      		id.setPrimaryKey(true);
      
      		// Alias
      		DataSourceTextField alias = new DataSourceTextField("alias", locale.alias());
      
      		// Documento Identidad
      		DataSourceField documentosIdentidad = new DataSourceField();
      		documentosIdentidad.setName("documentosIdentidad");
      		documentosIdentidad.setTitle(locale.documentoIdentidad());
      		documentosIdentidad.setTypeAsDataSource(DocumentoIdentidadDS.getInstance());
      
      		// Direccion
      		DataSourceField direcciones = new DataSourceField();
      		direcciones.setName("direcciones");
      		direcciones.setTitle(locale.direccion());
      		direcciones.setTypeAsDataSource(DireccionDS.getInstance());
      
      		// Medio de Contacto
      		DataSourceField mediosContacto = new DataSourceField();
      		mediosContacto.setName("mediosContacto");
      		mediosContacto.setTitle(locale.medioContacto());
      		mediosContacto.setTypeAsDataSource(MedioContactoDS.getInstance());
      
      		// Medio de Contacto
      		DataSourceField secuencia = new DataSourceField();
      		secuencia.setName("secuencia");
      		secuencia.setTitle(locale.serieFacturacion());
      		secuencia.setTypeAsDataSource(SecuenciaFrasDS.getInstance());
      
      		// Notas
      		DataSourceField notas = new DataSourceField();
      		notas.setName("notas");
      		notas.setTypeAsDataSource(NotaDS.getInstance());
      
      		// Es Cliente
      		DataSourceBooleanField esCliente = new DataSourceBooleanField("esCliente", locale.esCliente());
      
      		// Es Proveedor
      		DataSourceBooleanField esProveedor = new DataSourceBooleanField("esProveedor", locale.esProveedor());
      
      		// Valoración Proveedor
      		DataSourceEnumField valoracionProveedor = new DataSourceEnumField("valoracionProveedor",
      				locale.valoracionProveedor());
      		/*
      		 * Valoración correspondiente a ISO Arplatia. Si se modifica debe
      		 * modificarse también en InformeDynamicForm.java
      		 */
      		LinkedHashMap<String, String> valueMapValoracion = new LinkedHashMap<String, String>();
      		valueMapValoracion.put("A", "A");
      		valueMapValoracion.put("B", "B");
      		valoracionProveedor.setValueMap(valueMapValoracion);
      
      		// Valoración Proveedor
      		DataSourceTextField observacionValoracionProveedor = new DataSourceTextField("observacionValoracionProveedor",
      				locale.observacionValoracionProveedor());
      
      		// Activo
      		DataSourceBooleanField activo = new DataSourceBooleanField("activo", locale.activo());
      
      		// Día de presentación de facturas
      		DataSourceIntegerField cantidadDias = new DataSourceIntegerField("cantidadDias", locale.cantidadDias());
      
      		// Tipo de plazo de pago
      		DataSourceEnumField tipoPago = new DataSourceEnumField("tipoPago", locale.tipoPago());
      		LinkedHashMap<String, String> tipoPagoMap = new LinkedHashMap<String, String>(4);
      		tipoPagoMap.put("lineal", locale.lineal());
      		tipoPagoMap.put("mensual", locale.mensual());
      		tipoPagoMap.put("quincenal", locale.quincenal());
      		tipoPagoMap.put("mensualapartirDia", locale.mensualapartirDia());
      		tipoPago.setValueMap(tipoPagoMap);
      
      		DataSourceEnumField fechaDesde = new DataSourceEnumField("fechaDesde", locale.fechaDesde());
      		LinkedHashMap<String, String> fechaDesdeMap = new LinkedHashMap<String, String>(2);
      		fechaDesdeMap.put("factura", locale.factura());
      		// fechaDesdeMap.put("entregaVehiculo", locale.entregaVehiculo());
      		// fechaDesdeMap.put("recepcionPeritaje", locale.recepcionPeritaje());
      		fechaDesdeMap.put("mayorVehiculoPeritaje", locale.mayorVehiculoPeritaje());
      		fechaDesde.setValueMap(fechaDesdeMap);
      
      		DataSourceTextField observacionesPago = new DataSourceTextField("observacionesPago", locale.observacionesPago());
      
      		DataSourceEnumField tipoPagoDefecto = new DataSourceEnumField("tipoPagoDefecto", locale.tipoPagoDefecto());
      		LinkedHashMap<String, String> valueMapFormaPago = new LinkedHashMap<String, String>();
      		valueMapFormaPago.put("TRANSFERENCIABANCARIA", locale.formaPagoTransferencia());
      		valueMapFormaPago.put("EFECTIVO", locale.formaPagoEfectivo());
      		valueMapFormaPago.put("TALON_CHEQUE", locale.formaPagoTalonCheque());
      		valueMapFormaPago.put("DOMICILIADO", locale.formaPagoDomiciliado());
      		tipoPagoDefecto.setValueMap(valueMapFormaPago);
      
      		// Valor de plazo de pago
      		DataSourceIntegerField apartirDia = new DataSourceIntegerField("apartirDia", locale.apartirDia());
      		
      		// Modo de facturación
      		DataSourceEnumField modoFacturacion = new DataSourceEnumField("modoFacturacion", locale.modoFacturacion());
      		LinkedHashMap<String, String> modoFacturacionMap = new LinkedHashMap<String, String>(2);
      		modoFacturacionMap.put("individual", locale.modoFacturacionIndividual());
      		modoFacturacionMap.put("agrupada", locale.modoFacturacionAgrupada());
      		modoFacturacion.setValueMap(modoFacturacionMap);
      
      		// Relaciones cliente Taller
      		DataSourceField relacionesClienteTaller = new DataSourceField();
      		relacionesClienteTaller.setName("relacionesClienteTaller");
      		relacionesClienteTaller.setTitle(locale.relacionesClienteTaller());
      		relacionesClienteTaller.setTypeAsDataSource(RelacionesClienteTallerDS.getInstance());
      
      		// Cuenta de facturación
      		DataSourceTextField cuentaFacturacion = new DataSourceTextField("cuentaFacturacion", locale.cuentaFacturacion());
      
      		// Cuenta de facturación
      		DataSourceTextField cuentaFacturacionAlt = new DataSourceTextField("cuentaFacturacionAlt",
      				locale.cuentaFacturacionAlt());
      
      		// Condicion de parada
      		DataSourceField condicionesParada = new DataSourceField();
      		condicionesParada.setName("condicionesParada");
      		condicionesParada.setTitle(locale.condicionesParada());
      		condicionesParada.setTypeAsDataSource(CondicionParadaDS.getInstance());
      
      		// Asignar campos al DataSource
      		setFields(id, alias, documentosIdentidad, direcciones, mediosContacto, esCliente, esProveedor,
      				valoracionProveedor, observacionValoracionProveedor, cantidadDias, tipoPago, apartirDia, fechaDesde,
      				observacionesPago, tipoPagoDefecto, modoFacturacion, activo, notas, relacionesClienteTaller,
      				cuentaFacturacion, cuentaFacturacionAlt, condicionesParada, secuencia);
      	}
      }
      EmpresaGestoraDS
      Code:
      package com.arplatia.ns.client.contacto.empresaGestora.dataSource;
      
      import java.util.LinkedHashMap;
      
      import com.arplatia.ns.client.contacto.dataSource.ContactoDS;
      import com.arplatia.ns.client.contacto.empresaGestora.EmpresaGestoraConstants;
      import com.arplatia.ns.client.contacto.empresaGestora.cuentaBancaria.dataSource.CuentaBancariaDS;
      import com.arplatia.ns.client.util.JSONRestDataSource;
      import com.google.gwt.core.client.GWT;
      import com.smartgwt.client.data.DataSourceField;
      import com.smartgwt.client.data.fields.DataSourceEnumField;
      import com.smartgwt.client.data.fields.DataSourceTextField;
      
      public class EmpresaGestoraDS extends JSONRestDataSource {
      	// Locale
      	private EmpresaGestoraConstants locale = GWT.create(EmpresaGestoraConstants.class);
      
      	private static EmpresaGestoraDS instance = null;
      
      	public static EmpresaGestoraDS getInstance() {
      		if (instance == null) {
      			instance = new EmpresaGestoraDS("empresaGestoraDS");
      		}
      
      		return instance;
      	}
      
      	public EmpresaGestoraDS(String idDataSource) {
      		super();
      
      		// Establecer Id del DataSource
      		setID(idDataSource);
      
      		// Operaciones CRUD del REST
      		setFetchDataURL("rest/empresaGestora/fetch");
      		setAddDataURL("rest/empresaGestora/add");
      		setUpdateDataURL("rest/empresaGestora/update");
      		setRemoveDataURL("rest/empresaGestora/remove");
      
      		// Heredar de ContactoDS
      		setInheritsFrom(ContactoDS.getInstance());
      		setUseParentFieldOrder(true);
      
      		// Protocolo de SmartGWT
      		setSendMetaData(true);
      		setCacheAllData(false);
      		setAutoCacheAllData(false);
      
      		// Razón social
      		DataSourceTextField razonSocial = new DataSourceTextField("razonSocial", locale.razonSocial());
      
      		// Cuentas Bancarias
      		DataSourceField cuentasBancarias = new DataSourceField();
      		cuentasBancarias.setName("cuentasBancarias");
      		cuentasBancarias.setTitle(locale.cuentasBancarias());
      		cuentasBancarias.setTypeAsDataSource(CuentaBancariaDS.getInstance());
      
      		DataSourceTextField registroMercantil = new DataSourceTextField("registroMercantil", locale.registroMercantil());
      		DataSourceTextField logoGeneral = new DataSourceTextField("logoGeneral", locale.logoGeneral());
      		DataSourceTextField logoDocumentos = new DataSourceTextField("logoDocumentos", locale.logoDocumentos());
      
      		// Tipo de moneda por defecto
      		DataSourceEnumField tipoMoneda = new DataSourceEnumField("tipoMoneda", locale.tipoMoneda());
      		LinkedHashMap<String, String> valueMapTipoMoneda = new LinkedHashMap<String, String>();
      		valueMapTipoMoneda.put("EURO", locale.euro());
      		valueMapTipoMoneda.put("DOLAR", locale.dolar());
      		valueMapTipoMoneda.put("LIBRA", locale.libra());
      		valueMapTipoMoneda.put("PESO_MEX", locale.pesoMexico());
      		valueMapTipoMoneda.put("PESO_COL", locale.pesoColombia());
      		tipoMoneda.setValueMap(valueMapTipoMoneda);
      
      		// Asignar campos al DataSource
      		setFields(razonSocial, cuentasBancarias, registroMercantil, logoGeneral, logoDocumentos, tipoMoneda);
      	}
      }
      These DataSources extends from JSONRestDataSource witch is a customization of RestDataSource to use JSON and some transforms in request / response, but nothing related with preffix / suffix and working since the start of the project two years ago and through two major SmartGWT LGPL version updates

      JSONRestDataSource
      Code:
      package com.arplatia.ns.client.util;
      
      import com.arplatia.ns.client.sesion.Sesion;
      import com.google.gwt.core.client.JavaScriptObject;
      import com.smartgwt.client.data.DSRequest;
      import com.smartgwt.client.data.DSResponse;
      import com.smartgwt.client.data.DataSource;
      import com.smartgwt.client.data.OperationBinding;
      import com.smartgwt.client.data.Record;
      import com.smartgwt.client.data.RestDataSource;
      import com.smartgwt.client.data.SortSpecifier;
      import com.smartgwt.client.types.DSDataFormat;
      import com.smartgwt.client.types.DSOperationType;
      import com.smartgwt.client.types.DSProtocol;
      import com.smartgwt.client.util.JSOHelper;
      import com.smartgwt.client.widgets.Canvas;
      import com.smartgwt.client.widgets.grid.ListGrid;
      import com.smartgwt.client.widgets.grid.ListGridField;
      
      public abstract class JSONRestDataSource extends RestDataSource {
      
      	public JSONRestDataSource() {
      		// Definir formatos
      		setDataFormat(DSDataFormat.JSON);
      		setJsonRecordXPath("/response/data");
      		setSendMetaData(false);
      
      		// Operation Bindings
      		OperationBinding fetch = new OperationBinding();
      		fetch.setOperationType(DSOperationType.FETCH);
      		fetch.setDataProtocol(DSProtocol.POSTPARAMS);
      		OperationBinding add = new OperationBinding();
      		add.setOperationType(DSOperationType.ADD);
      		add.setDataProtocol(DSProtocol.POSTPARAMS);
      		OperationBinding update = new OperationBinding();
      		update.setOperationType(DSOperationType.UPDATE);
      		update.setDataProtocol(DSProtocol.POSTPARAMS);
      		OperationBinding remove = new OperationBinding();
      		remove.setOperationType(DSOperationType.REMOVE);
      		remove.setDataProtocol(DSProtocol.POSTPARAMS);
      		setOperationBindings(fetch, add, update, remove);
      
      		// Activar la caché si es posible
      		setAutoCacheAllData(true);
      	}
      
      	@Override
      	protected Object transformRequest(DSRequest dsRequest) {
      		// Si no hay datos, crear un objetivo JavaScript vacío
      		if (dsRequest.getData() == null) dsRequest.setData(JavaScriptObject.createObject());
      
      		/*
      		 * Si es una actualización, sobreescribimos el comportamiento de
      		 * SmartGWT para pasar como nuevos valores todos los campos del
      		 * DataSource.
      		 */
      		if (dsRequest.getOperationType() == DSOperationType.UPDATE) {
      			JavaScriptObject newData = JavaScriptObject.createObject();
      			JavaScriptObject oldValues = dsRequest.getAttributeAsJavaScriptObject("oldValues");
      			// Añadir valores no modificados
      			JSOHelper.apply(oldValues, newData);
      			JavaScriptObject data = dsRequest.getData();
      			// Unificar con valores modificados
      			JSOHelper.apply(data, newData);
      			// Guardar los datos
      			dsRequest.setData(newData);
      		}
      
      		/*
      		 * Eliminar las propiedades null en operaciones UPDATE / REMOVE para
      		 * evitar un error en el deserializador de Jersey. Al llegarle null, lo
      		 * deserializa como un string "null". Lo optimo sería corregirlo en
      		 * Jersey, pero no he encontrado forma de hacerlo.
      		 */
      		if (dsRequest.getOperationType() == DSOperationType.UPDATE
      				|| dsRequest.getOperationType() == DSOperationType.REMOVE) {
      			// Obtener los datos
      			JavaScriptObject data = dsRequest.getData();
      			// Obtener una relación de las propiedades
      			String[] arrayPropiedades = JSOHelper.getProperties(data);
      			for (String propiedad : arrayPropiedades) {
      				// Evitar propiedades propias de SmartGWT
      				if (!propiedad.startsWith("_") && !propiedad.startsWith("isc_")
      						&& JSOHelper.getAttribute(data, propiedad) == null) {
      					// Eliminar si es null
      					JSOHelper.deleteAttribute(data, propiedad);
      				}
      			}
      			// Asignar set de datos modificado al DSRequest
      			dsRequest.setData(data);
      		}
      
      		// Añadir la id del usuario que realiza la operación
      		if (Sesion.getUsuario() != null) {
      			JSOHelper.setAttribute(dsRequest.getData(), "usuarioId", Sesion.getUsuario().getAttribute("id"));
      		}
      
      		/*
      		 * Añadir la id del contacto asociado (si existe) que realiza la
      		 * operación FETCH
      		 */
      		if (Sesion.getUsuario() != null && Sesion.getUsuario().getAttributeAsRecord("contacto") != null
      				&& dsRequest.getOperationType() == DSOperationType.FETCH) {
      			// Asociar la id del contacto
      			JSOHelper.setAttribute(dsRequest.getData(), "contactoId",
      					Sesion.getUsuario().getAttributeAsRecord("contacto").getAttribute("id"));
      		}
      
      		/*
      		 * Añadir los tipos de los campos del DataSource a los datos del
      		 * DSRequest para realizar las comprobaciones necesarias en el servidor
      		 */
      		if (dsRequest.getDataSource() != null) {
      			DataSource dataSource = DataSource.get(dsRequest.getDataSource());
      			JavaScriptObject tiposDS = JavaScriptObject.createObject();
      			for (String name : dataSource.getFieldNames()) {
      				JSOHelper.setAttribute(tiposDS, name, dataSource.getField(name).getAttribute("type"));
      			}
      			JSOHelper.setAttribute(dsRequest.getData(), "types", tiposDS);
      		}
      
      		/*
      		 * Comprobar si hay ordenación y controlar si son campos de tablas
      		 * anidadas pasando el path completo del mismo al servidor. Sino, se
      		 * dejan tal cual
      		 */
      		if (dsRequest.getOperationType() == DSOperationType.FETCH && dsRequest.getSortBy() != null) {
      			// Obtener el canvas que realiza la petición
      			Canvas source = Canvas.getById(dsRequest.getComponentId());
      
      			// Comprobar que es un ListGrid
      			if (source != null && source instanceof ListGrid) {
      				ListGrid listGrid = (ListGrid) source;
      
      				// Obtener los campos de ordenación
      				SortSpecifier[] sortSpecifiers = dsRequest.getSortBy();
      				for (int i = 0; i < sortSpecifiers.length; i++) {
      					SortSpecifier sortSpecifier = sortSpecifiers[i];
      					/*
      					 * Forzar visibilidad del campo para evitar error en el
      					 * getField(), ya que devuelve null
      					 */
      					listGrid.showField(sortSpecifier.getField());
      					ListGridField listGridField = listGrid.getField(sortSpecifier.getField());
      					// Si tiene un path especificado es que es un campo anidado
      					if (listGridField.getDataPath() != null) sortSpecifier.setField(listGridField.getDataPath());
      				}
      
      				// Asignar los nuevos datos de ordenación
      				dsRequest.setSortBy(sortSpecifiers);
      			}
      		}
      
      		// Llamada original
      		return super.transformRequest(dsRequest);
      	}
      
      	@Override
      	protected void transformResponse(DSResponse response, DSRequest request, Object data) {
      		// Comprobar si estamos trabajando con selección de records
      		if (request.getAttributeAsRecord("data").getAttribute("isSelected") != null) {
      			// Obtener las Ids de los records seleccionados
      			String[] split = request.getAttributeAsRecord("data").getAttributeAsString("isSelected").split(";");
      
      			/*
      			 * Iterar sobre las Ids y los records que recibimos para marcarlos
      			 * como seleccionados en caso de coincidir la Id
      			 */
      			for (String recordId : split) {
      				for (Record record : response.getData()) {
      					if (recordId.equals(record.getAttributeAsString("id"))) {
      						// Marcar como seleccionado y salir del bucle
      						record.setAttribute("isSelected", true);
      						break;
      					}
      				}
      			}
      		}
      
      		// Llamada original
      		super.transformResponse(response, request, data);
      	}
      }
      Thanks for your support

      Comment


        #4
        We've fixed an issue we believe might have been causing the stack trace you reported in your initial post. The fix will be available in a nightly 9.1 build in the next few days.

        Regards,
        Isomorphic Software

        Comment


          #5
          Confirm the fix. Tested against today's (22/7/2014) patched version

          Thanks for your support

          Comment

          Working...
          X