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?
>>>>>>
>>>>>>
>>>>>>
>>>>>
>>>>
>>>
>>
>

Reply via email to