Below is a list of all Achilles annotations
Analyzer class to be used for SASI support. Possible values are:
Shutdown hook to control when to shutdown the embedded Cassandra process.
CassandraShutDownHook shutdownHook = new CassandraShutDownHook();
Session session = CassandraEmbeddedServerBuilder.builder()
.withShutdownHook(shutdownHook)
...
.buildNativeSession();
...
shutdownHook.shutdownNow();
Please note that upon call on shutdownNow(), Achilles will trigger the shutdown of:
This is an enum used to declare the Cassandra version you're using for compile to configure Achilles at compile time.
@CompileTimeConfig(cassandraVersion = CassandraVersion.CASSANDRA_3_0_X)
public interface AchillesConfig {
}
Depending on the chosen version, Achilles will generate appropriate DSL code.
Define a codec to transform a source type into a target type.
The source type can be any Java type. The target type should be a Java type supported by Cassandra
public interface Codec<FROM, TO> {
Class<FROM> sourceType();
Class<TO> targetType();
TO encode(FROM fromJava) throws AchillesTranscodingException;
FROM decode(TO fromCassandra) throws AchillesTranscodingException;
}
Example of LongToString codec:
public class LongToString implements Codec<Long,String> {
@Override
public Class<Long> sourceType() {
return Long.class;
}
@Override
public Class<String> targetType() {
return String.class;
}
@Override
public String encode(Long fromJava) throws AchillesTranscodingException {
return fromJava.toString();
}
@Override
public Long decode(String fromCassandra) throws AchillesTranscodingException {
return Long.parseLong(fromCassandra);
}
}
Utility class to identify uniquely a codec. A codec signature is composed of:
See Runtime Codec for more details
You can specify the column mapping strategy at compile time using the @CompileTimeConfig annotation:
@CompileTimeConfig(cassandraVersion = CassandraVersion.CASSANDRA_3_0_X, columnMappingStrategy = ColumnMappingStrategy.IMPLICIT)
public interface AchillesConfig {
}
The default behavior is ColumnMappingStrategy.EXPLICIT
See Column Mapping Strategy for more details
Define the encoding type for enum values. 2 choices are available:
info.archinnov.achilles.annotations.Enumerated.Encoding.NAME encode enum using their name()info.archinnov.achilles.annotations.Enumerated.Encoding.ORDINAL encode enum using their ordinal()More details on Enum type
It is just a marker enum for asynchronous operations. Sometimes an operation does not return any meaningful result
(like deleteById(...) or insert(...)).
Still we need to be able to ensure that the asynchronous operation has been executed correctly by calling get().
If the execution has been successful, the singleton Empty is returned, otherwise an exception is raised
For more details, please check Asynchronous Operations
Indexing mode for SASI. Possible values are:
Define the insert strategy on an entity. Right now only 2 values are possible:
info.archinnov.achilles.type.InsertStrategy.NOT_NULL_FIELDSinfo.archinnov.achilles.type.InsertStrategy.ALL_FIELDSUpon call to insert(), depending on the chosen strategy Achilles will
Check here for more details on the Insert strategy
This is an interface defining the contract for a lifecycle interceptor. For more details, please check Interceptors
public interface Interceptor<T>
{
boolean acceptEntity(Class<?> entityClass);
public void onEvent(T entity);
public List<Event> events();
}
For all LWT operations, Cassandra returns an [applied] boolean column telling whether the operation has been successful or not. If a LWT update operation failed, Cassandra also returns the current values that differ from the ones used by the LWT update.
To intercepts the LWT operation result and current values, you can register a LWTResultListener using the Options API (see above)
The signature of the LWTResultListener is:
public interface LWTResultListener {
default void onSuccess() {
// Do nothing
}
void onError(LWTResult lwtResult);
}
The LWTResult type is defined as:
public class LWTResult {
private final Operation operation;
private final TypedMap currentValues;
public LWTResult(Operation operation, TypedMap currentValues) {
this.operation = operation;
this.currentValues = currentValues;
}
...
public static enum Operation {INSERT, UPDATE}
}
For more details on LWT operations, please refer to Lightweight Transaction
Define the naming strategy for the keyspace, table and column name. There are 3 possible strategies:
Check here for more details on the Naming strategy
Text normalization mode for SASI. Possible values are:
This is an interface to be implemented to provide dynamic binding of keyspace/table name at runtime.
The interface is
public interface SchemaNameProvider {
/**
* Provide keyspace name for entity class
*/
<T> String keyspaceFor(Class<T> entityClass);
/**
* Provide table name for entity class
*/
<T> String tableNameFor(Class<T> entityClass);
}
The provider can be used with CRUD API and DSL API
Since Cassandra supports tuple type and the Java driver only exposes a com.datastax.driver.core.TupleValue,
Achilles introduces Tuple1, Tuple2, ..., Tuple10 types. They all extends the Tuple interface
and exposes the following methods:
//Get all tuple values, in the correct order
public List<Object> values();
//Return the 1st component of the tuple
public A _1();
//Return the 2nd component of the tuple
public B _2();
...
//Return the 10th component of the tuple
public J _10();
Internally, Achilles will perform automatic conversion between those tuple types to/from
com.datastax.driver.core.TupleValueso that you can use them directly in your entities
@Table
public class Entity {
@Column
private Tuple3<String, List<String>, Long> tuple3;
...
}
Note: in the above example, there is no need to add
@Frozenon theList<String>
because all tuples are frozen by default.
The native query API used to return a Map<String,Object> as result. It is not very user-friendly because it forces you do manual type casting. Example:
Map<String,Object> columns = manager.nativeQuery("SELECT * FROM users WHERE userId = 10").getFirst();
String name = (String)columns.get("name"); // BAD !
Long age = (Long)columns.get("age"); // BAD !
TypedMap is just an extension of Map<String,Object> offering two extras methods for convenience:
@SuppressWarnings("unchecked")
public <T> T getTyped(String key) {
T value = null;
if (super.containsKey(key) && super.get(key) != null) {
value = (T) super.get(key);
return value;
}
return value;
}
public <T> T getTypedOr(String key, T defaultValue) {
if (super.containsKey(key)) {
return getTyped(key);
} else {
return defaultValue;
}
}
Of course there is no magic, the dirty casting you no longer do, getTyped() will do it for you. The target type is passed at runtime while calling the method. getTypedOr() lets you provide a fall-back value.
Example of usage:
TypedMap columns = manager.nativeQuery("SELECT * FROM users WHERE userId = 10").first();
// Explicit type (String) is passed to method invocation
String name = columns.<String>getTyped("name");
// No need to provide explicit type. The compiler will infer type in this case
Long age = columns.get("age");