You're viewing documentation for a previous version of Scylla Java Driver. Switch to the latest stable version.
Advanced topic, only needed if you use Java serialization with driver rows or data types, or create tuple or UDT types manually.
Some driver components need to keep an internal reference to their originating Session. Under specific circumstances, they can lose that reference, and you might need to reattach them.
Namely, these components are:
Detachable types are an advanced topic, that should only be a concern for 3rd-party tool developers. If you’re simply executing requests and reading results, you probably won’t need to worry about them. See the bottom line at the end of this page for details.
Detachable components are those that encode or decode their fields themselves. For example, when you set a field on a tuple value:
tupleValue = tupleValue.setString(0, "foo");
The string “foo” is encoded immediately, and the
TupleValue object holds a reference to the binary
data. It is done that way in order to fail fast on encoding errors, and avoid duplicate work if you
reuse the tuple instance in multiple requests.
Encoding requires session-specific information:
the protocol version (because the binary format can change across versions).
Therefore the tuple value needs a reference to the session to access those two objects.
Detachable types implement the Detachable interface, which has an
isDetached() method to check
the current status. Whenever you get an object from the driver, it is attached:
reading a row from a result set:
ResultSet rs = session.execute("SELECT * FROM foo"); Row row = rs.one(); assert !row.isDetached();
reading a data type from schema metadata:
UserDefinedType udt = session.getMetadata().getKeyspace("ks").getUserDefinedType("type1"); assert !udt.isDetached();
There is no way to detach an object explicitly. This can only happen when:
deserializing a previously serialized instance (we’re referring here to Java serialization);
attaching an object to another session;
TupleType tupleType = DataTypes.tupleOf(DataTypes.INT, DataTypes.TEXT, DataTypes.FLOAT); assert tupleType.isDetached();
When an object is detached, it uses a default codec registry that only handles built-in types, and the latest non-beta protocol version supported by the driver. This might be good enough for you if you don’t use any custom codec (the binary format has been stable across modern protocol versions).
attach() to reattach an object to the session:
TupleType tupleType = DataTypes.tupleOf(DataTypes.INT, DataTypes.TEXT, DataTypes.FLOAT); assert tupleType.isDetached(); tupleType.attach(session.getContext()); assert !tupleType.isDetached(); // Now this will use the session's custom codecs if field 0 isn't a text CQL type: TupleValue tupleValue = tupleType.newValue().setString(0, "foo");
When you pass a detached type to the session (for example by executing a request with a tuple value based on a detached tuple type), it will automatically be reattached.
If you’re reading data from one session and writing it into another, you should take a few extra precautions:
if you use custom codecs, they should obviously be registered with both sessions;
if the protocol version is different, you should avoid sharing UDT and tuple types; keep a separate set of definitions for each session, and copy the values field by field:
Row row = session1.execute("SELECT QUERY...").one(); UdtValue user1 = row.getUdtValue("user"); // Don't pass user1 to session2: create a new copy from userType2 instead UserDefinedType userType2 = session2.getMetadata().getKeyspace("ks").flatMap(ks -> ks.getUserDefinedType("user")).get(); UdtValue user2 = userType2.newValue(); user2.setString("first_name", user1.getString("first_name")); user2.setString("last_name", user1.getString("last_name")); session2.execute(SimpleStatement.newInstance("INSERT QUERY...", user2));
This will ensure that UDT definition are not accidentally reattached to the wrong session, and use the correct protocol version to encode values.