Or it could even take Set<label> as the first bound var: void addLabel(Set<Label> label, String id);
On Sat, Nov 12, 2016 at 8:41 PM, Ali Akhtar <ali.rac...@gmail.com> wrote: > Andrew, > > I was thinking about setting up an accessor with that query and a bound > variable ? which binds to the instance being added, e.g: > > @Query("UPDATE my_table SET labels = labels + ? WHERE id = ?") > void addLabel(Label label, String id); > > Will that work? > > On Sat, Nov 12, 2016 at 8:38 PM, Andrew Tolbert < > andrew.tolb...@datastax.com> wrote: > >> You can do it in a SimpleStatement assuming you provide the CQL exactly >> as you provided, but in a PreparedStatement it will not work because cql >> prohibits provide bind values in collection literals. For it to work you >> could provide a List of UDT values in a bound prepared statement, i.e.: >> >> UserType udtType = cluster.getMetadata().getKeysp >> ace("k").getUserType("u"); >> UDTValue value = udtType.newValue(); >> value.setString(0, "data"); >> >> PreparedStatement p0 = session.prepare("UPDATE my_table SET labels = >> labels + ? where id = ?"); >> BoundStatement b0 = p0.bind(*Lists.newArrayList(value)*, 0); >> session.execute(b0); >> >> Thanks, >> Andy >> >> On Sat, Nov 12, 2016 at 9:02 AM, Ali Akhtar <ali.rac...@gmail.com> wrote: >> >>> Looks like the trick was to use [] around the udt value literal. >>> >>> Any way to do this using the java driver? >>> >>> On Sat, Nov 12, 2016 at 7:58 PM, Ali Akhtar <ali.rac...@gmail.com> >>> wrote: >>> >>>> Changing the double quotes to single quotes gives: >>>> >>>> UPDATE my_table SET labels = labels + {id: 'foo'} where id = ''; >>>> >>>> InvalidRequest: Error from server: code=2200 [Invalid query] >>>> message="Invalid user type literal for labels of type list<frozen<label>>" >>>> >>>> >>>> On Sat, Nov 12, 2016 at 7:50 PM, Ali Akhtar <ali.rac...@gmail.com> >>>> wrote: >>>> >>>>> The question is about appending to a set of frozen<udt> and how to do >>>>> that while avoiding the race condition. >>>>> >>>>> If I run: >>>>> >>>>> UPDATE my_table SET labels = labels + {id: "foo"} where id = 'xx'; >>>>> >>>>> I get: >>>>> >>>>> SyntaxException: line 1:57 no viable alternative at input '}' (...= >>>>> labels + {id: ["fo]o"}...) >>>>> >>>>> Here labels is set<frozen<label>> >>>>> >>>>> On Sat, Nov 12, 2016 at 7:40 PM, Vladimir Yudovin < >>>>> vla...@winguzone.com> wrote: >>>>> >>>>>> If I used consistency = ALL both when getting the record, and when >>>>>> saving the record, will that avoid the race condition? >>>>>> If I use consistency level = all, will that cause it to end up with >>>>>> [1,2]? >>>>>> No. Even if you have only one host it's possible that two threads >>>>>> first both read data and than overwrite existing value one by one. >>>>>> >>>>>> The list is actually of a list<frozen<my_udt>> and not a text (I used >>>>>> text for simplification, apologies). >>>>>> In that case, will updates still merge the list values instead of >>>>>> overwriting them? >>>>>> Do you mean UPDATE cql operation? Yes, it adds new values to list, >>>>>> allowing duplicates. >>>>>> >>>>>> When setting a new value to a list, C* will do a read-delete-write >>>>>> internally e.g. read the current list, remove all its value (by a range >>>>>> tombstone) and then write the new list. >>>>>> As I mentioned duplicates are allowed in LIST, and as DOC says: >>>>>> >>>>>> These update operations are implemented internally without any >>>>>> read-before-write. Appending and prepending a new element to the >>>>>> list writes only the new element. >>>>>> >>>>>> Only when using index >>>>>> >>>>>> When you add an element at a particular position, Cassandra reads the >>>>>> entire list, and then writes only the updated element. Consequently, >>>>>> adding >>>>>> an element at a particular position results in greater latency than >>>>>> appending or prefixing an element to a list. >>>>>> >>>>>> >>>>>> Best regards, Vladimir Yudovin, >>>>>> >>>>>> *Winguzone <https://winguzone.com?from=list> - Hosted Cloud >>>>>> CassandraLaunch your cluster in minutes.* >>>>>> >>>>>> >>>>>> ---- On Sat, 12 Nov 2016 07:57:36 -0500*Ali Akhtar >>>>>> <ali.rac...@gmail.com <ali.rac...@gmail.com>>* wrote ---- >>>>>> >>>>>> The labels collection is of the type set<frozen<label>> , where label >>>>>> is a udt containing: id, name, description , all text fields. >>>>>> >>>>>> On Sat, Nov 12, 2016 at 5:54 PM, Ali Akhtar <ali.rac...@gmail.com> >>>>>> wrote: >>>>>> >>>>>> The problem isn't just the update / insert though, right? Don't >>>>>> frozen entities get overwritten completely? So if I had [1] [2] being >>>>>> written as updates, won't each update overwrite the set completely, so >>>>>> i'll >>>>>> end up with either one of them instead of [1,2]? >>>>>> >>>>>> On Sat, Nov 12, 2016 at 5:50 PM, DuyHai Doan <doanduy...@gmail.com> >>>>>> wrote: >>>>>> >>>>>> Maybe you should use my Achilles mapper, which does generates UPDATE >>>>>> statements on collections and not only INSERT >>>>>> Le 12 nov. 2016 13:08, "Ali Akhtar" <ali.rac...@gmail.com> a écrit : >>>>>> >>>>>> I am using the Java Cassandra mapper for all of these cases, so my >>>>>> code looks like this: >>>>>> >>>>>> Item myItem = myaccessor.get( itemId ); >>>>>> Mapper<Item> mapper = mappingManager.create( Item.class ); >>>>>> >>>>>> myItem.labels.add( newLabel ); >>>>>> mapper.save( myItem ); >>>>>> >>>>>> On Sat, Nov 12, 2016 at 5:06 PM, Ali Akhtar <ali.rac...@gmail.com> >>>>>> wrote: >>>>>> >>>>>> Thanks DuyHai, I will switch to using a set. >>>>>> >>>>>> But I'm still not sure how to resolve the original question. >>>>>> >>>>>> - Original labels = [] >>>>>> - Request 1 arrives with label = 1, and request 2 arrives with label >>>>>> = 2 >>>>>> - Updates are sent to c* with labels = [1] and labels = [2] >>>>>> simultaneously. >>>>>> >>>>>> What will happen in the above case? Will it cause the labels to end >>>>>> up as [1,2] (what I want) or either [1] or [2]? >>>>>> >>>>>> If I use consistency level = all, will that cause it to end up with >>>>>> [1,2]? >>>>>> >>>>>> On Sat, Nov 12, 2016 at 4:59 PM, DuyHai Doan <doanduy...@gmail.com> >>>>>> wrote: >>>>>> >>>>>> Don't use list, use set instead. If you need ordering of insertion, >>>>>> use a map<timeuuid,text> where timeuuid is generated by the client to >>>>>> guarantee insertion order >>>>>> >>>>>> When setting a new value to a list, C* will do a read-delete-write >>>>>> internally e.g. read the current list, remove all its value (by a range >>>>>> tombstone) and then write the new list. Please note that prepend & append >>>>>> operations on list do not require this read-delete-write and thus >>>>>> performs >>>>>> slightly better >>>>>> >>>>>> On Sat, Nov 12, 2016 at 11:34 AM, Ali Akhtar <ali.rac...@gmail.com> >>>>>> wrote: >>>>>> >>>>>> I have a table where each record contains a list<string> of labels. >>>>>> >>>>>> I have an endpoint which responds to new labels being added to a >>>>>> record by the user. >>>>>> >>>>>> Consider the following scenario: >>>>>> >>>>>> - Record X, labels = [] >>>>>> - User selects 2 labels, clicks a button, and 2 http requests are >>>>>> generated. >>>>>> - The server receives request for Label 1 and Label 2 at the same >>>>>> time. >>>>>> - Both requests see the labels as empty, add 1 label to the >>>>>> collection, and send it. >>>>>> - Record state as label 1 request sees it: [1], as label 2 sees it: >>>>>> [2] >>>>>> >>>>>> How will the above conflict be resolved? What can I do so I end up >>>>>> with [1, 2] instead of either [1] or [2] after both requests have been >>>>>> processed? >>>>>> >>>>>> >>>>>> >>>>> >>>> >>> >> >