Go Back   SmartClient Forums > Smart GWT Technical Q&A
Wiki Register Search Today's Posts Mark Forums Read

Reply
 
Thread Tools Search this Thread
  #1  
Old 9th Jun 2012, 11:54
ls3674 ls3674 is offline
Registered Developer
 
Join Date: Sep 2011
Posts: 129
Default MutliUpdate Flag Set. 1 Record Updating

I have a custom operation that is called when a user closes a Window. It is meant to clean up after a user by marking several items in the database that belong to them for deletion with a soft-delete flag.

The way the call works, is that when a user closes a window, a custom operation on a datasource is called and in the DSRequest is passed an IP Address.

Code:
<operationBinding operationType="custom" allowMultiUpdate="true" operationId="deleteUserDestinationsByIPAddress" serverMethod="deleteUserDestinationsByIPAddress"/>
Once the request makes it to the server, all records for a certain table are looked up via a fetch:

Code:
DataSource vsd = DataSourceManager.get("videoStreamDestination");
            List<VideoStreamDestination> records = vsd.fetch("ipAddress",dsRequest.getFieldValue("ipAddress").toString());
Once the List of records matching the IP Address criteria are fetched, they are looped over and new maps are created with the proper values set, so that a setValues(newVals) call can be made on the DSRequest.

Code:
ArrayList<Map<String,Object>> updatedDestinations = new ArrayList<Map<String, Object>>();

            //iterate the entity list and make maps out of the objects
            for(VideoStreamDestination destination : records)
            {
                destination.setDeletedFlag(true);
                Map<String, Object> destinationMap = new HashMap<String, Object>();
                destinationMap.put("id",destination.getId());
                destinationMap.put("ipAddress",destination.getIpAddress());
                destinationMap.put("portNumber",destination.getPortNumber());
                destinationMap.put("creator",destination.getCreatorName());
                destinationMap.put("deletedFlag",true);
                updatedDestinations.add(destinationMap);
            }
Once all the maps are created and values set, the call to setValues is made and the a call to the execute method is made on the DataSource

Code:
 dsRequest.setValues(updatedDestinations);
            dsRequest.setOperationType(DSOperationType.UPDATE.toString().toLowerCase());
            //dsRequest.setAllowMultiUpdate(true);
            vsd.execute(dsRequest);
note: the allowMultiUpdate property is set in the ds.xml for this data source, and reading the documentation it seemed like that was the flag to set for allowing multiple updates.

The problem is that when this request is executed, only one record is updated, and the following is seen in the logs, notice: WARN DSRequest - getValues() called on dsRequest containing multiple sets of values, returning first in list.....

12:51:13,367 INFO [stdout] (http-0.0.0.0-0.0.0.0-8080-4) === 2012-06-09 12:51:13,367 [80-4] INFO IDACall - Performing 1 operation(s)
12:51:13,369 INFO [stdout] (http-0.0.0.0-0.0.0.0-8080-4) === 2012-06-09 12:51:13,369 [80-4] DEBUG ServerObject - Couldn't find a public method named: fetch on class: com.sncorp.gs2.ui.server.dmi.VideoStreamDestinatio nDMI
12:51:13,370 INFO [stdout] (http-0.0.0.0-0.0.0.0-8080-4) === 2012-06-09 12:51:13,370 [80-4] DEBUG DataSourceDMI - DataSourceDMI: no public method name: fetch available on class: com.sncorp.gs2.ui.server.dmi.VideoStreamDestinatio nDMI - defaulting to builtin operations.
12:51:13,371 INFO [stdout] (http-0.0.0.0-0.0.0.0-8080-4) === 2012-06-09 12:51:13,371 [80-4] DEBUG AppBase - [builtinApplication.null] No userTypes defined, allowing anyone access to all operations for this application
12:51:13,371 INFO [stdout] (http-0.0.0.0-0.0.0.0-8080-4) === 2012-06-09 12:51:13,371 [80-4] DEBUG AppBase - [builtinApplication.null] No public zero-argument method named '_null' found, performing generic datasource operation
12:51:13,372 INFO [stdout] (http-0.0.0.0-0.0.0.0-8080-4) === 2012-06-09 12:51:13,372 [80-4] DEBUG JPADataSource - [builtinApplication.null] Creating EntityManager and starting transaction.
12:51:13,378 INFO [stdout] (http-0.0.0.0-0.0.0.0-8080-4) === 2012-06-09 12:51:13,378 [80-4] DEBUG JPADataSource - [builtinApplication.null] Executing fetch.
12:51:13,378 INFO [stdout] (http-0.0.0.0-0.0.0.0-8080-4) === 2012-06-09 12:51:13,378 [80-4] DEBUG JPADataSource - [builtinApplication.null] Query string: select _VideoStreamDestination from VideoStreamDestination _VideoStreamDestination where (lower(_VideoStreamDestination.ipAddress) = lower(:p0))
12:51:13,380 INFO [stdout] (http-0.0.0.0-0.0.0.0-8080-4) === 2012-06-09 12:51:13,380 [80-4] DEBUG JPADataSource - [builtinApplication.null] Parameter p0: 127.0.0.1
12:51:13,391 INFO [stdout] (http-0.0.0.0-0.0.0.0-8080-4) === 2012-06-09 12:51:13,391 [80-4] INFO DSResponse - [builtinApplication.null] DSResponse: List with 3 items
12:51:13,391 INFO [stdout] (http-0.0.0.0-0.0.0.0-8080-4) === 2012-06-09 12:51:13,391 [80-4] DEBUG JPADataSource - [builtinApplication.null] Committing current transaction.
12:51:13,397 INFO [stdout] (http-0.0.0.0-0.0.0.0-8080-4) === 2012-06-09 12:51:13,397 [80-4] DEBUG JPADataSource - [builtinApplication.null] Releasing entity manager.
12:51:13,398 INFO [stdout] (http-0.0.0.0-0.0.0.0-8080-4) === 2012-06-09 12:51:13,398 [80-4] DEBUG JPADataSource - Releasing entity manager.
12:51:13,399 INFO [stdout] (http-0.0.0.0-0.0.0.0-8080-4) === 2012-06-09 12:51:13,399 [80-4] DEBUG JPADataSource - Auto-joining transactions.
12:51:13,399 INFO [stdout] (http-0.0.0.0-0.0.0.0-8080-4) === 2012-06-09 12:51:13,399 [80-4] DEBUG JPADataSource - Creating EntityManager, starting transaction and setting it to RPCManager.
12:51:13,405 INFO [stdout] (http-0.0.0.0-0.0.0.0-8080-4) === 2012-06-09 12:51:13,405 [80-4] DEBUG DSRequest - Clobbering existing FreeResourcesHandler of type 'com.sncorp.gs2.ui.server.datasource.RTMDataSource ' with a 'com.sncorp.gs2.ui.server.datasource.RTMDataSource '
12:51:13,406 INFO [stdout] (http-0.0.0.0-0.0.0.0-8080-4) === 2012-06-09 12:51:13,406 [80-4] DEBUG JPADataSource - Executing update.
12:51:13,406 INFO [stdout] (http-0.0.0.0-0.0.0.0-8080-4) === 2012-06-09 12:51:13,406 [80-4] WARN DSRequest - getValues() called on dsRequest containing multiple sets of values, returning first in list.
12:51:13,416 INFO [stdout] (http-0.0.0.0-0.0.0.0-8080-4) === 2012-06-09 12:51:13,416 [80-4] WARN DSRequest - getValues() called on dsRequest containing multiple sets of values, returning first in list.
12:51:13,419 INFO [stdout] (http-0.0.0.0-0.0.0.0-8080-4) === 2012-06-09 12:51:13,419 [80-4] DEBUG RPCManager - Content type for RPC transaction: text/plain; charset=UTF-8
12:51:13,419 INFO [stdout] (http-0.0.0.0-0.0.0.0-8080-4) === 2012-06-09 12:51:13,419 [80-4] DEBUG JPADataSource - Committing transaction for 1 queued operation(s).
12:51:13,424 INFO [stdout] (pool-12-thread-1) === 2012-06-09 12:51:13,424 [ad-1] DEBUG ISCMessageDispatcher - sending message to channel: DATASOURCE_CHANNEL
12:51:13,425 INFO [stdout] (http-0.0.0.0-0.0.0.0-8080-4) === 2012-06-09 12:51:13,425 [80-4] DEBUG RPCManager - DMI response, dropExtraFields: false
12:51:13,427 INFO [stdout] (http-0.0.0.0-0.0.0.0-8080-4) === 2012-06-09 12:51:13,427 [80-4] DEBUG JPADataSource - Releasing entity manager.

What can I do to have all of the updates take place?
Reply With Quote
  #2  
Old 9th Jun 2012, 12:21
Isomorphic Isomorphic is offline
Administrator
 
Join Date: May 2006
Posts: 30,561
Default

Assuming the same soft delete flag is being applied to all Records, you should provide one set of values and then Criteria or AdvancedCriteria that will select all Records. Then it's all one SQL operation.

Alternatively, create on DSRequest per update operation.
Reply With Quote
  #3  
Old 11th Jun 2012, 08:32
ls3674 ls3674 is offline
Registered Developer
 
Join Date: Sep 2011
Posts: 129
Default

So setting the values on the DSRequest as a map doesn't mark them all for update?

Code:
dsRequest.setValues(updatedDestinations);
The documentation for that method on DSRequest reads:
Quote:
Sets the values for this DSRequest. You may pass either a Map or a List of Maps. The List type is typically used for a DataSource.OP_ADD operation with multiple records.
I'm not quite following.

Last edited by ls3674; 11th Jun 2012 at 09:18..
Reply With Quote
  #4  
Old 11th Jun 2012, 10:07
Isomorphic Isomorphic is offline
Administrator
 
Join Date: May 2006
Posts: 30,561
Default

The format of multiple Maps is for certain unusual operations which aren't supported by JPA DataSource. Also this is for "add" not "update".

So again you'll want either Criteria/AdvancedCriteria that target all records with the same values, or one DSRequest per record you want to update.
Reply With Quote
  #5  
Old 11th Jun 2012, 10:52
ls3674 ls3674 is offline
Registered Developer
 
Join Date: Sep 2011
Posts: 129
Default

So there is no such thing as a true multi-update? Instead I need to loop over the records obtained by my criteria:
Code:
DataSource vsd = DataSourceManager.get("videoStreamDestination");
            List<VideoStreamDestination> records = vsd.fetch("ipAddress",dsRequest.getFieldValue("ipAddress").toString());
, update it, put the values in a map, create a new DSRequest instance, assign the value of the updated map, and then call execute?

Small nag here, but the documentation says that setValues() is generally used for adds. It doesn't say that it's not used for other operations.
Reply With Quote
  #6  
Old 11th Jun 2012, 11:03
Isomorphic Isomorphic is offline
Administrator
 
Join Date: May 2006
Posts: 30,561
Default

What do you mean by "a true multi-update"?

Leaving aside some weird possibilities in JPA/Hibernate, one DSRequest results in one SQL operation. If you put together criteria that affect all records, you'll have one SQL UPDATE affecting multiple records. If for some reason you can't form a single criteria, then you'll have several SQL UPDATE operations.

Is there some third possibility you're looking for?
Reply With Quote
  #7  
Old 11th Jun 2012, 11:50
ls3674 ls3674 is offline
Registered Developer
 
Join Date: Sep 2011
Posts: 129
Default

I've obviously missed something here. I'm trying to set the values in a bunch of maps in a loop. That loop is being performed on a List<Entity> gotten from a server-side fetch. Once through the loop and the map is updated, I set the values on the dataSource via setValues(). I then called execute on the dataSource passing it the dsRequest.

I also broke it up to execute a new update dsRequest each time through the loop with no success.

I gather from our back-and-forth that this is not at all the way to do it. You recommend setting a criteria on the dsRequest. How is that accomplished to perform an update? Do you have an example?

Specifically, how does one set a criteria to say, "Update the deleted_flag field to true for every record with ipAddress = "127.0.0.1"?
Reply With Quote
  #8  
Old 11th Jun 2012, 11:56
Isomorphic Isomorphic is offline
Administrator
 
Join Date: May 2006
Posts: 30,561
Default

You set the criteria for a DSRequest with dsRequest.setCriteria(). Criteria that would select/update all records with ipAddress 127.0.0.1 is just:

Code:
Map criteria = new HashMap();
criteria.put("ipAddress", "127.0.0.1");
If you want to affect multiple IP addresses with the same values, you can pass an Array or List to put().

There is also setAdvancedCriteria() and the AdvancedCriteria APIs if you need to do something more sophisticated (like ipAddress = "something" AND hostName is null) OR (..)).
Reply With Quote
  #9  
Old 11th Jun 2012, 12:51
ls3674 ls3674 is offline
Registered Developer
 
Join Date: Sep 2011
Posts: 129
Default

So I'm trying to do all of this on the server, not the client, a criteria doesn't do any good there.

My use-case is this, send ip to server and then perform all updates there. I think we've been talking apples and oranges.
Reply With Quote
  #10  
Old 11th Jun 2012, 13:13
Isomorphic Isomorphic is offline
Administrator
 
Join Date: May 2006
Posts: 30,561
Default

ds.setCriteria() and AdvancedCriteria are server APIs.

To take a guess at what's confusing you - you may think criteria means "search"/"fetch". It doesn't. "update" and "remove" DSRequests have criteria, and, like the WHERE clause in a SQL UPDATE or DELETE, it specifies what records are updated or deleted.
Reply With Quote
Reply


Thread Tools Search this Thread
Search this Thread:

Advanced Search


Similar Threads
Thread Thread Starter Forum Replies Last Post
CanvasItem value management markok Smart GWT Technical Q&A 60 13th Apr 2013 12:59
Need a way to control logging outside war/log4j.isc.config.xml maksymg Smart GWT Technical Q&A 9 7th Jan 2013 01:35
ListGrid record components jpappalardo Smart GWT Technical Q&A 14 12th Apr 2012 05:43
Problem during evaluation re: updating joined data peterunivex Smart GWT Technical Q&A 16 11th Jan 2011 09:06
New record ID when updating catalinmerfu Technical Q&A 2 5th May 2008 11:28

© 2010,2011 Isomorphic Software. All Rights Reserved