
com.datastax.driver.mapping.MappingSession Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of cassandra-driver-mapping Show documentation
Show all versions of cassandra-driver-mapping Show documentation
Entity Mapping Addon JPA 2.1 compatible for DataStax Java Driver 3.0+ for Cassandra.
/*
* Copyright (C) 2014 Eugene Valchkou.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.datastax.driver.mapping;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Logger;
import com.datastax.driver.core.BoundStatement;
import com.datastax.driver.core.PreparedStatement;
import com.datastax.driver.core.RegularStatement;
import com.datastax.driver.core.ResultSet;
import com.datastax.driver.core.ResultSetFuture;
import com.datastax.driver.core.Row;
import com.datastax.driver.core.Session;
import com.datastax.driver.core.Statement;
import com.datastax.driver.core.querybuilder.Batch;
import com.datastax.driver.core.querybuilder.BuiltStatement;
import com.datastax.driver.core.querybuilder.QueryBuilder;
import com.datastax.driver.mapping.builder.MappingBuilder;
import com.datastax.driver.mapping.meta.EntityTypeMetadata;
import com.datastax.driver.mapping.option.BatchOptions;
import com.datastax.driver.mapping.option.ReadOptions;
import com.datastax.driver.mapping.option.WriteOptions;
import com.datastax.driver.mapping.schemasync.SchemaSync;
import com.google.common.cache.Cache;
/**
* Object Mapper API to work with entities to be persisted in Cassandra. This is
* lightweight wrapper for the datastax Session. This class is ThreadSafe and
* can be shared. Create one instance per datastax Session or create a new one
* for each request. Example:
*
*
* MappingSession msession = new MappingSession(keyspace, session);
* msession.save(entity);
* msession.get(Entity.class, id);
* msession.delete(entity);
*
*/
public class MappingSession {
protected static final Logger log = Logger.getLogger(MappingSession.class.getName());
protected Session session;
protected String keyspace;
protected boolean doNotSync;
public MappingSession() {
super();
}
/**
* Constructor
*
* @param keyspace name
* @param session Initialized Datastax Session
*/
public MappingSession(String keyspace, Session session) {
this(keyspace, session, false);
}
/**
* Constructor
*
* @param keyspace name
* @param session Initialized Datastax Session
* @param doNotSync if set to true the mappingSession will not synchronize
* entity definition with Cassandra
*/
public MappingSession(String keyspace, Session session, boolean doNotSync) {
this.session = session;
this.keyspace = keyspace;
this.doNotSync = doNotSync;
}
/**
* Get Entity by Id(Primary Key)
*
* @param class Entity.class
* @param id primary key
* @return Entity instance or null
*/
public T get(Class clazz, Object id) {
return get(clazz, id, null);
}
/**
* Get Entity by Id(Primary Key)
*
* @param class Entity.class
* @param id primary key
* @param options ReadOptions
* @return Entity instance or null
*/
public T get(Class clazz, Object id, ReadOptions options) {
maybeSync(clazz);
BoundStatement bs = MappingBuilder.prepareSelect(clazz, id, options, keyspace, session);
if (bs != null) {
ResultSet rs = session.execute(bs);
List all = getFromResultSet(clazz, rs);
if (all.size() > 0) {
return all.get(0);
}
}
return null;
}
/**
* Get Collection of Entities by custom Query Statement
*
* @param class Entity.class
* @param query Statement
* @return List if nothing is retrieved empty List is
* returned
*/
public List getByQuery(Class clazz, Statement query) {
maybeSync(clazz);
return getFromResultSet(clazz, session.execute(query));
}
/**
* Get Collection of Entities by custom Query String
*
* @param class Entity.class
* @param query String
* @return List if nothing is retrieved empty List is
* returned
*/
public List getByQuery(Class clazz, String query) {
maybeSync(clazz);
return getFromResultSet(clazz, session.execute(query));
}
/**
* Convert custom ResultSet into List. No Cassandra invocations are
* performed.
*
* @param class Entity.class
* @param query String
* @return List or empty List if nothing mapped.
*/
public List getFromResultSet(Class clazz, ResultSet rs) {
return MappingBuilder.getFromResultSet(clazz, rs);
}
/**
* Delete Entity
*
* @param entity
*/
public void delete(E entity) {
maybeSync(entity.getClass());
BuiltStatement bs = MappingBuilder.buildDelete(entity, keyspace);
execute(bs);
}
/**
* Delete Entity by ID(Primary key)
*
* @param class Entity.class
* @param id Primary Key
*/
public void delete(Class clazz, Object id) {
maybeSync(clazz);
BuiltStatement bs = MappingBuilder.buildDelete(clazz, id, keyspace);
execute(bs);
}
/**
* Asynchronously Delete Entity
*
* @param entity
* @return ResultSetFuture
*/
public ResultSetFuture deleteAsync(E entity) {
maybeSync(entity.getClass());
BuiltStatement bs = MappingBuilder.buildDelete(entity, keyspace);
return executeAsync(bs);
}
/**
* Asynchronously Delete Entity by ID(Primary key)
*
* @param class Entity.class
* @param id Primary Key
*/
public ResultSetFuture deleteAsync(Class clazz, Object id) {
maybeSync(clazz);
BuiltStatement bs = MappingBuilder.buildDelete(clazz, id, keyspace);
return executeAsync(bs);
}
/**
* Save Entity. If Entity has @Version field, in attempt to save not the
* latest version null is returned.
*
* @param entity
* @return ResultSetFuture.
*/
public E save(E entity) {
return save(entity, null);
}
/**
* Save Entity. If Entity has @Version field, in attempt to save not the
* latest version the entity will not be saved and no Exceptions will be
* thrown.
*
* @param entity
* @return ResultSetFuture.
*/
public ResultSetFuture saveAsync(E entity) {
return saveAsync(entity, null);
}
/**
* Save Entity. If Entity has @Version field, in attempt to save not the
* latest version null is returned.
*
* @param entity
* @param options WriteOptions
* @return ResultSetFuture.
*/
public E save(E entity, WriteOptions options) {
maybeSync(entity.getClass());
Statement stmt = MappingBuilder.prepareSave(entity, options, keyspace);
ResultSet rs = session.execute(stmt);
EntityTypeMetadata entityMetadata = EntityTypeParser.getEntityMetadata(entity.getClass());
if (entityMetadata.hasVersion()) {
Row row = rs.one();
if (!(row != null && row.getBool("[applied]"))) {
return null;
}
}
return entity;
}
/**
* Asynchronously Save Entity. If Entity has @Version field, in attempt to
* save not the latest version the entity will not be saved and no
* Exceptions will be thrown.
*
* @param entity
* @param options WriteOptions
* @return ResultSetFuture.
*/
public ResultSetFuture saveAsync(E entity, WriteOptions options) {
maybeSync(entity.getClass());
Statement stmt = MappingBuilder.prepareSave(entity, options, keyspace);
return executeAsync(stmt);
}
/**
* Remove an item or items from the Set or List.
*
* @param id Primary Key
* @param class Entity.class
* @param propertyName property of Entity to modify
* @param item can be single value, a List or a Set of values to remove.
*/
public void remove(Object id, Class> clazz, String propertyName, Object item) {
maybeSync(clazz);
BoundStatement bs = MappingBuilder.prepareRemoveItemsFromSetOrList(id, clazz, propertyName, item, keyspace, session);
execute(bs);
}
/**
* Asynchronously Remove an item or items from the Set or List.
*
* @param id Primary Key
* @param class Entity.class
* @param propertyName property of Entity to modify
* @param item can be single value, a List or a Set of values to remove.
* @return ResultSetFuture.
*/
public ResultSetFuture removeAsync(Object id, Class> clazz, String propertyName, Object item) {
maybeSync(clazz);
BoundStatement bs = MappingBuilder.prepareRemoveItemsFromSetOrList(id, clazz, propertyName, item, keyspace, session);
return executeAsync(bs);
}
/**
* Delete value for an individual property
*
* @param id Primary Key
* @param class Entity.class
* @param propertyName Entity property
*/
public void deleteValue(Object id, Class> clazz, String propertyName) {
maybeSync(clazz);
BoundStatement bs = MappingBuilder.prepareDelete(id, clazz, propertyName, keyspace, session);
execute(bs);
}
/**
* Asynchronously Delete value for an individual property
*
* @param id Primary Key
* @param class Entity.class
* @param propertyName Entity property
* @return ResultSetFuture.
*/
public ResultSetFuture deleteValueAsync(Object id, Class> clazz, String propertyName) {
maybeSync(clazz);
BoundStatement bs = MappingBuilder.prepareDelete(id, clazz, propertyName, keyspace, session);
return executeAsync(bs);
}
/**
* Asynchronously Append value or values to the Set, List or Map.
*
* @param id Primary Key
* @param class Entity.class
* @param propertyName Entity property
* @param item can be a single value, a List, Set or a Map of values
*/
public void append(Object id, Class> clazz, String propertyName, Object item) {
append(id, clazz, propertyName, item, null);
}
/**
* Append value or values to the Set, List or Map.
*
* @param id Primary Key
* @param class Entity.class
* @param propertyName Entity property
* @param item can be a single value, a List, Set or a Map of values
* @param options WriteOptions
*/
public void append(Object id, Class> clazz, String propertyName, Object item, WriteOptions options) {
maybeSync(clazz);
BoundStatement bs = MappingBuilder.prepareAppendItemToCollection(id, clazz, propertyName, item, options, keyspace, session);
execute(bs);
}
/**
* Asynchronously Append value or values to the Set, List or Map.
*
* @param id Primary Key
* @param class Entity.class
* @param propertyName Entity property
* @param item can be a single value, a List, Set or a Map of values
* @return ResultSetFuture.
*/
public ResultSetFuture appendAsync(Object id, Class> clazz, String propertyName, Object item) {
return appendAsync(id, clazz, propertyName, item, null);
}
/**
* Asynchronously Append value or values to the Set, List or Map.
*
* @param id Primary Key
* @param class Entity.class
* @param propertyName Entity property
* @param item can be a single value, a List, Set or a Map of values
* @param options WriteOptions
* @return ResultSetFuture.
*/
public ResultSetFuture appendAsync(Object id, Class> clazz, String propertyName, Object item, WriteOptions options) {
maybeSync(clazz);
BoundStatement bs = MappingBuilder.prepareAppendItemToCollection(id, clazz, propertyName, item, options, keyspace, session);
return executeAsync(bs);
}
/**
* Replace existing value with a new one.
*
* @param id Primary Key
* @param class Entity.class
* @param propertyName Entity property
* @param value new value
*/
public void updateValue(Object id, Class> clazz, String propertyName, Object value) {
updateValue(id, clazz, propertyName, value, null);
}
/**
* Asynchronously Replace existing value with a new one.
*
* @param id Primary Key
* @param class Entity.class
* @param propertyName Entity property
* @param value new value
* @return ResultSetFuture.
*/
public ResultSetFuture updateValueAsync(Object id, Class> clazz, String propertyName, Object value) {
return updateValueAsync(id, clazz, propertyName, value, null);
}
/**
* Replace existing value with a new one.
*
* @param id Primary Key
* @param class Entity.class
* @param propertyName Entity property
* @param value new value
* @param options WriteOptions
*/
public void updateValue(Object id, Class> clazz, String propertyName, Object value, WriteOptions options) {
maybeSync(clazz);
BoundStatement bs = MappingBuilder.prepareUpdateValue(id, clazz, propertyName, value, options, keyspace, session);
execute(bs);
}
/**
* Asynchronously Replace existing value with a new one.
*
* @param id Primary Key
* @param class Entity.class
* @param propertyName Entity property
* @param value new value
* @param options WriteOptions
* @return ResultSetFuture.
*/
public ResultSetFuture updateValueAsync(Object id, Class> clazz, String propertyName, Object value, WriteOptions options) {
maybeSync(clazz);
BoundStatement bs = MappingBuilder.prepareUpdateValue(id, clazz, propertyName, value, options, keyspace, session);
return executeAsync(bs);
}
/**
* Place item or items at the beginning of the List.
*
* @param id Primary Key
* @param class Entity.class
* @param propertyName Entity property
* @param item can be a single item or a List of items
*/
public void prepend(Object id, Class> clazz, String propertyName, Object item) {
prepend(id, clazz, propertyName, item, null);
}
/**
* Asynchronously Place item or items at the beginning of the List.
*
* @param id Primary Key
* @param class Entity.class
* @param propertyName Entity property
* @param item can be a single item or a List of items
* @return ResultSetFuture.
*/
public ResultSetFuture prependAsync(Object id, Class> clazz, String propertyName, Object item) {
return prependAsync(id, clazz, propertyName, item, null);
}
/**
* Place item or items at the beginning of the List.
*
* @param id Primary Key
* @param class Entity.class
* @param propertyName Entity property
* @param item can be a single item or a List of items
* @param options WriteOptions
*/
public void prepend(Object id, Class> clazz, String propertyName, Object item, WriteOptions options) {
maybeSync(clazz);
BoundStatement bs = MappingBuilder.preparePrependItemToList(id, clazz, propertyName, item, options, keyspace, session);
execute(bs);
}
/**
* Asynchronously Place item or items at the beginning of the List.
*
* @param id Primary Key
* @param class Entity.class
* @param propertyName Entity property
* @param item can be a single item or a List of items
* @param options WriteOptions
* @return ResultSetFuture.
*/
public ResultSetFuture prependAsync(Object id, Class> clazz, String propertyName, Object item, WriteOptions options) {
maybeSync(clazz);
BoundStatement bs = MappingBuilder.preparePrependItemToList(id, clazz, propertyName, item, options, keyspace, session);
return executeAsync(bs);
}
/**
* Replace item at the specified position in the List.
*
* @param id Primary Key
* @param class Entity.class
* @param propertyName Entity property
* @param item
* @param idx index of the item to replace. Starts from 0.
*/
public void replaceAt(Object id, Class> clazz, String propertyName, Object item, int idx) {
replaceAt(id, clazz, propertyName, item, idx, null);
}
/**
* Asynchronously Replace item at the specified position in the List.
*
* @param id Primary Key
* @param class Entity.class
* @param propertyName Entity property
* @param item
* @param idx index of the item to replace. Starts from 0.
* @return ResultSetFuture.
*/
public ResultSetFuture replaceAtAsync(Object id, Class> clazz, String propertyName, Object item, int idx) {
return replaceAtAsync(id, clazz, propertyName, item, idx, null);
}
/**
* Replace item at the specified position in the List.
*
* @param id Primary Key
* @param class Entity.class
* @param propertyName Entity property
* @param item
* @param idx index of the item to replace. Starts from 0.
* @param options WriteOptions
*/
public void replaceAt(Object id, Class> clazz, String propertyName, Object item, int idx, WriteOptions options) {
maybeSync(clazz);
BoundStatement bs = MappingBuilder.prepareReplaceAt(id, clazz, propertyName, item, idx, options, keyspace, session);
execute(bs);
}
/**
* Asynchronously Replace item at the specified position in the List.
*
* @param id Primary Key
* @param class Entity.class
* @param propertyName Entity property
* @param item
* @param idx index of the item to replace. Starts from 0.
* @param options WriteOptions
* @return ResultSetFuture.
*/
public ResultSetFuture replaceAtAsync(Object id, Class> clazz, String propertyName, Object item, int idx, WriteOptions options) {
maybeSync(clazz);
BoundStatement bs = MappingBuilder.prepareReplaceAt(id, clazz, propertyName, item, idx, options, keyspace, session);
return executeAsync(bs);
}
public BatchExecutor withBatch() {
return new BatchExecutor(this);
}
/** This Class is wrapper for batch operations. */
public static class BatchExecutor {
List statements = new ArrayList();
MappingSession m;
Batch b;
public BatchExecutor(MappingSession m) {
this.m = m;
b = QueryBuilder.batch(new RegularStatement[0]);
}
public BatchExecutor delete(E entity) {
b.add(MappingBuilder.buildDelete(entity, m.keyspace));
return this;
}
public BatchExecutor save(E entity) {
save(entity, null);
return this;
}
public BatchExecutor save(E entity, WriteOptions options) {
m.maybeSync(entity.getClass());
b.add(MappingBuilder.prepareSave(entity, options, m.keyspace));
return this;
}
/**
* Apply Options to the whole batch statement.
*
* @param options
*/
public void withOptions(BatchOptions options) {
if (options != null) {
if (options.getConsistencyLevel() != null) {
b.setConsistencyLevel(options.getConsistencyLevel());
}
if (options.getRetryPolicy() != null) {
b.setRetryPolicy(options.getRetryPolicy());
}
}
}
/** execute batch statement */
public void execute() {
m.session.execute(b);
}
/**
* Asynchronously execute batch statement
*
* @return ResultSetFuture
*/
public ResultSetFuture executeAsync() {
return m.session.executeAsync(b);
}
}
/** @return true if sync is turned off. */
public boolean isDoNotSync() {
return doNotSync;
}
/**
* Turn sync off for all entities. Entity definitions will not be synced
* with Cassandra within this MappingSession.
*
* @param doNotSynch true|false
*/
public void setDoNotSync(boolean doNotSynch) {
this.doNotSync = doNotSynch;
}
/**
* get PreparedStatement Cache. May be used to retrieve cache statistics or
* to access cache directly.
*
* @param statementCache
*/
public static Cache getStatementCache() {
return MappingBuilder.getStatementCache();
}
/**
* replace default PreparedStatement Cache with your customized one.
*
* @param statementCache
*/
public static void setStatementCache(Cache statementCache) {
MappingBuilder.setStatementCache(statementCache);
}
protected void execute(BoundStatement bs) {
if (bs != null) {
session.execute(bs);
}
}
protected void execute(Statement s) {
if (s != null) {
session.execute(s);
}
}
protected ResultSetFuture executeAsync(BoundStatement bs) {
if (bs != null) {
return session.executeAsync(bs);
}
return null;
}
protected ResultSetFuture executeAsync(Statement s) {
if (s != null) {
return session.executeAsync(s);
}
return null;
}
/** run sync if not yet done */
protected void maybeSync(Class> clazz) {
if (doNotSync)
return; // forced to skip sync
EntityTypeMetadata entityMetadata = EntityTypeParser.getEntityMetadata(clazz);
if (!entityMetadata.isSynced(keyspace)) {
SchemaSync.sync(keyspace, session, clazz);
}
}
public Session getSession() {
return session;
}
public void setSession(Session session) {
this.session = session;
}
public String getKeyspace() {
return keyspace;
}
public void setKeyspace(String keyspace) {
this.keyspace = keyspace;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy