Skip to content

Commit 51e563d

Browse files
Alexandre Dutraolim7t
authored andcommitted
JAVA-922: Make TypeCodec return mutable collections.
This commit relaxes the postconditions on immutability stated in the javadocs for some methods in these classes. This commit also updates the javadocs of GettableByIndexData and GettableByNameData accordingly. It also prunes Row class and removes all duplicated method declarations. The Upgrade guide is updated with behavioral changes introduced by this commit.
1 parent 7d41629 commit 51e563d

6 files changed

Lines changed: 179 additions & 694 deletions

File tree

changelog/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
- [new feature] Add BoundStatement#unset (JAVA-930)
1212
- [bug] Make table metadata options class visible (JAVA-946)
1313
- [bug] Add crcCheckChance to TableOptionsMetadata#equals/hashCode (JAVA-939)
14+
- [bug] Make TypeCodec return mutable collections (JAVA-922)
1415

1516

1617
### 3.0.0-alpha3

driver-core/src/main/java/com/datastax/driver/core/GettableByIndexData.java

Lines changed: 82 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -258,13 +258,19 @@ public interface GettableByIndexData {
258258
* Returns the {@code i}th value as a list.
259259
* <p>
260260
* If the type of the elements is generic, use {@link #getList(int, TypeToken)}.
261+
* <p>
262+
* Implementation note: the actual {@link List} implementation will depend
263+
* on the {@link TypeCodec codec} being used; therefore, callers should
264+
* make no assumptions concerning its mutability nor its thread-safety.
265+
* Furthermore, the behavior of this method in respect to CQL {@code NULL} values is also
266+
* codec-dependent. By default, the driver will return mutable instances, and
267+
* a CQL {@code NULL} will mapped to an empty collection (note that Cassandra
268+
* makes no distinction between {@code NULL} and an empty collection).
261269
*
262270
* @param i the index ({@code 0 <= i < size()}) to retrieve.
263271
* @param elementsClass the class for the elements of the list to retrieve.
264272
* @return the value of the {@code i}th element as a list of
265-
* {@code T} objects. If the value is NULL, an empty list is
266-
* returned (note that Cassandra makes no difference between an empty list
267-
* and column of type list that is not set). The returned list is immutable.
273+
* {@code T} objects.
268274
*
269275
* @throws IndexOutOfBoundsException if {@code i} is not a valid index for this object.
270276
* @throws InvalidTypeException if value {@code i} is not a list or if its
@@ -279,13 +285,19 @@ public interface GettableByIndexData {
279285
* <pre>
280286
* {@code List<List<String>> l = row.getList(1, new TypeToken<List<String>>() {});}
281287
* </pre>
288+
* <p>
289+
* Implementation note: the actual {@link List} implementation will depend
290+
* on the {@link TypeCodec codec} being used; therefore, callers should
291+
* make no assumptions concerning its mutability nor its thread-safety.
292+
* Furthermore, the behavior of this method in respect to CQL {@code NULL} values is also
293+
* codec-dependent. By default, the driver will return mutable instances, and
294+
* a CQL {@code NULL} will mapped to an empty collection (note that Cassandra
295+
* makes no distinction between {@code NULL} and an empty collection).
282296
*
283297
* @param i the index ({@code 0 <= i < size()}) to retrieve.
284298
* @param elementsType the type of the elements of the list to retrieve.
285299
* @return the value of the {@code i}th element as a list of
286-
* {@code T} objects. If the value is NULL, an empty list is
287-
* returned (note that Cassandra makes no difference between an empty list
288-
* and column of type list that is not set). The returned list is immutable.
300+
* {@code T} objects.
289301
*
290302
* @throws IndexOutOfBoundsException if {@code i} is not a valid index for this object.
291303
* @throws InvalidTypeException if value {@code i} is not a list or if its
@@ -297,13 +309,19 @@ public interface GettableByIndexData {
297309
* Returns the {@code i}th value as a set.
298310
* <p>
299311
* If the type of the elements is generic, use {@link #getSet(int, TypeToken)}.
312+
* <p>
313+
* Implementation note: the actual {@link Set} implementation will depend
314+
* on the {@link TypeCodec codec} being used; therefore, callers should
315+
* make no assumptions concerning its mutability nor its thread-safety.
316+
* Furthermore, the behavior of this method in respect to CQL {@code NULL} values is also
317+
* codec-dependent. By default, the driver will return mutable instances, and
318+
* a CQL {@code NULL} will mapped to an empty collection (note that Cassandra
319+
* makes no distinction between {@code NULL} and an empty collection).
300320
*
301321
* @param i the index ({@code 0 <= i < size()}) to retrieve.
302322
* @param elementsClass the class for the elements of the set to retrieve.
303323
* @return the value of the {@code i}th element as a set of
304-
* {@code T} objects. If the value is NULL, an empty set is
305-
* returned (note that Cassandra makes no difference between an empty set
306-
* and column of type set that is not set). The returned set is immutable.
324+
* {@code T} objects.
307325
*
308326
* @throws IndexOutOfBoundsException if {@code i} is not a valid index for this object.
309327
* @throws InvalidTypeException if value {@code i} is not a set or if its
@@ -318,13 +336,19 @@ public interface GettableByIndexData {
318336
* <pre>
319337
* {@code Set<List<String>> l = row.getSet(1, new TypeToken<List<String>>() {});}
320338
* </pre>
339+
* <p>
340+
* Implementation note: the actual {@link Set} implementation will depend
341+
* on the {@link TypeCodec codec} being used; therefore, callers should
342+
* make no assumptions concerning its mutability nor its thread-safety.
343+
* Furthermore, the behavior of this method in respect to CQL {@code NULL} values is also
344+
* codec-dependent. By default, the driver will return mutable instances, and
345+
* a CQL {@code NULL} will mapped to an empty collection (note that Cassandra
346+
* makes no distinction between {@code NULL} and an empty collection).
321347
*
322348
* @param i the index ({@code 0 <= i < size()}) to retrieve.
323349
* @param elementsType the type for the elements of the set to retrieve.
324350
* @return the value of the {@code i}th element as a set of
325-
* {@code T} objects. If the value is NULL, an empty set is
326-
* returned (note that Cassandra makes no difference between an empty set
327-
* and column of type set that is not set). The returned set is immutable.
351+
* {@code T} objects.
328352
*
329353
* @throws IndexOutOfBoundsException if {@code i} is not a valid index for this object.
330354
* @throws InvalidTypeException if value {@code i} is not a set or if its
@@ -336,15 +360,20 @@ public interface GettableByIndexData {
336360
* Returns the {@code i}th value as a map.
337361
* <p>
338362
* If the type of the keys and/or values is generic, use {@link #getMap(int, TypeToken, TypeToken)}.
363+
* <p>
364+
* Implementation note: the actual {@link Map} implementation will depend
365+
* on the {@link TypeCodec codec} being used; therefore, callers should
366+
* make no assumptions concerning its mutability nor its thread-safety.
367+
* Furthermore, the behavior of this method in respect to CQL {@code NULL} values is also
368+
* codec-dependent. By default, the driver will return mutable instances, and
369+
* a CQL {@code NULL} will mapped to an empty collection (note that Cassandra
370+
* makes no distinction between {@code NULL} and an empty collection).
339371
*
340372
* @param i the index ({@code 0 <= i < size()}) to retrieve.
341373
* @param keysClass the class for the keys of the map to retrieve.
342374
* @param valuesClass the class for the values of the map to retrieve.
343375
* @return the value of the {@code i}th element as a map of
344-
* {@code K} to {@code V} objects. If the value is NULL,
345-
* an empty map is returned (note that Cassandra makes no difference
346-
* between an empty map and column of type map that is not set). The
347-
* returned map is immutable.
376+
* {@code K} to {@code V} objects.
348377
*
349378
* @throws IndexOutOfBoundsException if {@code i} is not a valid index for this object.
350379
* @throws InvalidTypeException if value {@code i} is not a map, if its
@@ -361,15 +390,20 @@ public interface GettableByIndexData {
361390
* <pre>
362391
* {@code Map<Int, List<String>> l = row.getMap(1, TypeToken.of(Integer.class), new TypeToken<List<String>>() {});}
363392
* </pre>
393+
* <p>
394+
* Implementation note: the actual {@link Map} implementation will depend
395+
* on the {@link TypeCodec codec} being used; therefore, callers should
396+
* make no assumptions concerning its mutability nor its thread-safety.
397+
* Furthermore, the behavior of this method in respect to CQL {@code NULL} values is also
398+
* codec-dependent. By default, the driver will return mutable instances, and
399+
* a CQL {@code NULL} will mapped to an empty collection (note that Cassandra
400+
* makes no distinction between {@code NULL} and an empty collection).
364401
*
365402
* @param i the index ({@code 0 <= i < size()}) to retrieve.
366403
* @param keysType the type for the keys of the map to retrieve.
367404
* @param valuesType the type for the values of the map to retrieve.
368405
* @return the value of the {@code i}th element as a map of
369-
* {@code K} to {@code V} objects. If the value is NULL,
370-
* an empty map is returned (note that Cassandra makes no difference
371-
* between an empty map and column of type map that is not set). The
372-
* returned map is immutable.
406+
* {@code K} to {@code V} objects.
373407
*
374408
* @throws IndexOutOfBoundsException if {@code i} is not a valid index for this object.
375409
* @throws InvalidTypeException if value {@code i} is not a map, if its
@@ -411,12 +445,16 @@ public interface GettableByIndexData {
411445
* If a second, custom codec for the same CQL type is registered, which one will
412446
* be used is unspecified; in such cases, it is preferable to use
413447
* the more deterministic methods {@link #get(int, Class)} or {@link #get(int, TypeToken)} instead.
448+
* <p>
449+
* Implementation note: the actual object returned by this method will depend
450+
* on the {@link TypeCodec codec} being used; therefore, callers should
451+
* make no assumptions concerning its mutability nor its thread-safety.
452+
* Furthermore, the behavior of this method in respect to CQL {@code NULL} values is also
453+
* codec-dependent; by default, a CQL {@code NULL} value translates to {@code null} for
454+
* simple types, UDTs and tuples, and to empty collections for all CQL collection types.
414455
*
415456
* @param i the index to retrieve.
416457
* @return the value of the {@code i}th value as the Java type matching its CQL type.
417-
* If the value is NULL and is a simple type, UDT or tuple, {@code null} is returned.
418-
* If it is NULL and is a collection type, an empty (immutable) collection is returned.
419-
*
420458
* @throws IndexOutOfBoundsException if {@code i} is not a valid index for this object.
421459
*/
422460
public Object getObject(int i);
@@ -431,12 +469,17 @@ public interface GettableByIndexData {
431469
* where more than one codec is registered for the same CQL type; specifying the Java class
432470
* allows the {@link CodecRegistry} to narrow down the search and return only an exactly-matching codec (if any),
433471
* thus avoiding any risk of ambiguity.
472+
* <p>
473+
* Implementation note: the actual object returned by this method will depend
474+
* on the {@link TypeCodec codec} being used; therefore, callers should
475+
* make no assumptions concerning its mutability nor its thread-safety.
476+
* Furthermore, the behavior of this method in respect to CQL {@code NULL} values is also
477+
* codec-dependent; by default, a CQL {@code NULL} value translates to {@code null} for
478+
* simple CQL types, UDTs and tuples, and to empty collections for all CQL collection types.
434479
*
435480
* @param i the index to retrieve.
436481
* @param targetClass The Java type the value should be converted to.
437482
* @return the value of the {@code i}th value converted to the given Java type.
438-
* If the CQL value is {@code NULL}, this method will return {@code null}
439-
* for a simple type, UDT or tuple, and an empty (immutable) collection for collection types.
440483
* @throws IndexOutOfBoundsException if {@code i} is not a valid index for this object.
441484
* @throws com.datastax.driver.core.exceptions.CodecNotFoundException
442485
* if no {@link TypeCodec} instance for {@code targetClass} could be found
@@ -454,12 +497,17 @@ public interface GettableByIndexData {
454497
* where more than one codec is registered for the same CQL type; specifying the Java class
455498
* allows the {@link CodecRegistry} to narrow down the search and return only an exactly-matching codec (if any),
456499
* thus avoiding any risk of ambiguity.
500+
* <p>
501+
* Implementation note: the actual object returned by this method will depend
502+
* on the {@link TypeCodec codec} being used; therefore, callers should
503+
* make no assumptions concerning its mutability nor its thread-safety.
504+
* Furthermore, the behavior of this method in respect to CQL {@code NULL} values is also
505+
* codec-dependent; by default, a CQL {@code NULL} value translates to {@code null} for
506+
* simple CQL types, UDTs and tuples, and to empty collections for all CQL collection types.
457507
*
458508
* @param i the index to retrieve.
459509
* @param targetType The Java type the value should be converted to.
460510
* @return the value of the {@code i}th value converted to the given Java type.
461-
* If the CQL value is {@code NULL}, the default set of codecs will return {@code null}
462-
* for a simple type, UDT or tuple, and an empty (immutable) collection for collection types.
463511
* @throws IndexOutOfBoundsException if {@code i} is not a valid index for this object.
464512
* @throws com.datastax.driver.core.exceptions.CodecNotFoundException
465513
* if no {@link TypeCodec} instance for {@code targetType} could be found
@@ -475,6 +523,13 @@ public interface GettableByIndexData {
475523
* <p>
476524
* It is the caller's responsibility to ensure that the given codec {@link TypeCodec#accepts(DataType) accepts}
477525
* the underlying CQL type; failing to do so may result in {@link InvalidTypeException}s being thrown.
526+
* <p>
527+
* Implementation note: the actual object returned by this method will depend
528+
* on the {@link TypeCodec codec} being used; therefore, callers should
529+
* make no assumptions concerning its mutability nor its thread-safety.
530+
* Furthermore, the behavior of this method in respect to CQL {@code NULL} values is also
531+
* codec-dependent; by default, a CQL {@code NULL} value translates to {@code null} for
532+
* simple CQL types, UDTs and tuples, and to empty collections for all CQL collection types.
478533
*
479534
* @param i the index to retrieve.
480535
* @param codec The {@link TypeCodec} to use to deserialize the value; may not be {@code null}.

0 commit comments

Comments
 (0)