@@ -99,6 +99,7 @@ import com.datastax.driver.core.querybuilder.Update;
|
||||
public class CqlTemplate extends CassandraAccessor implements CqlOperations {
|
||||
|
||||
protected static final Executor RUN_RUNNABLE_EXECUTOR = new Executor() {
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("all")
|
||||
public void execute(Runnable command) {
|
||||
@@ -856,48 +857,50 @@ public class CqlTemplate extends CassandraAccessor implements CqlOperations {
|
||||
|
||||
/**
|
||||
* Attempts to translate the {@link Exception} into a Spring Data {@link Exception}.
|
||||
* @param ex the Exception
|
||||
* @return the translated {@link RuntimeException}
|
||||
*
|
||||
* @param e the {@link Exception} to translate.
|
||||
* @return the translated {@link RuntimeException}.
|
||||
* @see <a href="http://docs.spring.io/spring/docs/current/spring-framework-reference/htmlsingle/#dao-exceptions">Consistent exception hierarchy</a>
|
||||
*/
|
||||
@SuppressWarnings("all")
|
||||
protected RuntimeException translateExceptionIfPossible(Exception ex) {
|
||||
return translateExceptionIfPossible(ex, getExceptionTranslator());
|
||||
protected RuntimeException translateExceptionIfPossible(Exception e) {
|
||||
return translateExceptionIfPossible(e, getExceptionTranslator());
|
||||
}
|
||||
|
||||
/**
|
||||
* Tries to convert the given {@link RuntimeException} into a {@link DataAccessException} but returns the original
|
||||
* exception if the conversation failed. Thus allows safe re-throwing of the return value.
|
||||
*
|
||||
* @param ex the exception to translate
|
||||
* @param e the exception to translate
|
||||
* @param exceptionTranslator the {@link PersistenceExceptionTranslator} to be used for translation
|
||||
* @return
|
||||
*/
|
||||
@SuppressWarnings("all")
|
||||
protected static RuntimeException translateExceptionIfPossible(Exception ex, PersistenceExceptionTranslator exceptionTranslator) {
|
||||
|
||||
Assert.notNull(ex, "Exception must not be null");
|
||||
Assert.notNull(exceptionTranslator, "PersistenceExceptionTranslator must not be null");
|
||||
|
||||
if (ex instanceof RuntimeException) {
|
||||
return potentiallyConvertRuntimeException((RuntimeException) ex, exceptionTranslator);
|
||||
}
|
||||
|
||||
return new CassandraUncategorizedDataAccessException("Caught Uncategorized Exception", ex);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tries to convert the given {@link RuntimeException} into a {@link DataAccessException} but returns the original
|
||||
* exception if the conversation failed. Thus allows safe re-throwing of the return value.
|
||||
*
|
||||
* @param ex the exception to translate
|
||||
* @param exceptionTranslator the {@link PersistenceExceptionTranslator} to be used for translation
|
||||
* @return
|
||||
*/
|
||||
private static RuntimeException potentiallyConvertRuntimeException(RuntimeException ex,
|
||||
protected static RuntimeException translateExceptionIfPossible(Exception e,
|
||||
PersistenceExceptionTranslator exceptionTranslator) {
|
||||
|
||||
RuntimeException resolved = exceptionTranslator.translateExceptionIfPossible(ex);
|
||||
return resolved == null ? ex : resolved;
|
||||
Assert.notNull(e, "Exception must not be null");
|
||||
Assert.notNull(exceptionTranslator, "PersistenceExceptionTranslator must not be null");
|
||||
|
||||
return (e instanceof RuntimeException) ? potentiallyConvertRuntimeException((RuntimeException) e, exceptionTranslator)
|
||||
: new CassandraUncategorizedDataAccessException("Caught Uncategorized Exception", e);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tries to convert the given {@link RuntimeException} into a {@link DataAccessException} but returns the original
|
||||
* exception if the conversation failed. Thus allows safe re-throwing of the return value.
|
||||
*
|
||||
* @param e the exception to translate
|
||||
* @param exceptionTranslator the {@link PersistenceExceptionTranslator} to be used for translation
|
||||
* @return
|
||||
*/
|
||||
@SuppressWarnings("all")
|
||||
private static RuntimeException potentiallyConvertRuntimeException(RuntimeException e,
|
||||
PersistenceExceptionTranslator exceptionTranslator) {
|
||||
|
||||
RuntimeException resolved = exceptionTranslator.translateExceptionIfPossible(e);
|
||||
|
||||
return (resolved != null ? resolved : e);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -56,12 +56,12 @@ public interface CassandraOperations extends CqlOperations {
|
||||
* Executes the given select {@code query} on the entity table of the specified {@code type} backed by a Cassandra
|
||||
* {@link com.datastax.driver.core.ResultSet}.
|
||||
* <p>
|
||||
* Returns a {@link java.util.Iterator} that wraps the a Cassandra {@link com.datastax.driver.core.ResultSet}.
|
||||
*
|
||||
* @param <T> element return type
|
||||
* @param query must not be empty and not {@literal null}.
|
||||
* @param type must not be {@literal null}.
|
||||
* @return
|
||||
* Returns a {@link java.util.Iterator} that wraps the Cassandra {@link com.datastax.driver.core.ResultSet}.
|
||||
*
|
||||
* @param <T> element return type.
|
||||
* @param query query to execute. Must not be empty or {@literal null}.
|
||||
* @param type Class type of the elements in the {@link Iterator} stream. Must not be {@literal null}.
|
||||
* @return an {@link Iterator} (stream) over the elements in the query result set.
|
||||
* @since 1.5
|
||||
*/
|
||||
<T> Iterator<T> stream(String query, Class<T> type);
|
||||
|
||||
@@ -602,15 +602,22 @@ public class CassandraTemplate extends CqlTemplate implements CassandraOperation
|
||||
|
||||
@Override
|
||||
public ResultSet doInSession(Session s) throws DataAccessException {
|
||||
return s.execute(query);
|
||||
return s.execute(logCql(query));
|
||||
}
|
||||
});
|
||||
|
||||
if (resultSet == null) {
|
||||
return Collections.<T>emptyList().iterator();
|
||||
}
|
||||
return (resultSet != null ? toIterator(resultSet, type) : Collections.<T>emptyIterator());
|
||||
}
|
||||
|
||||
return new ResultSetIteratorAdapter(resultSet.iterator(), getExceptionTranslator(), new CassandraConverterRowCallback<T>(cassandraConverter, type));
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.cassandra.core.CassandraTemplate.ResultSetIteratorAdapter
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
private <T> Iterator<T> toIterator(ResultSet resultSet, Class<T> type) {
|
||||
|
||||
return new ResultSetIteratorAdapter(resultSet.iterator(), getExceptionTranslator(),
|
||||
new CassandraConverterRowCallback<T>(cassandraConverter, type));
|
||||
}
|
||||
|
||||
protected <T> List<T> select(final Select query, CassandraConverterRowCallback<T> readRowCallback) {
|
||||
@@ -1109,7 +1116,7 @@ public class CassandraTemplate extends CqlTemplate implements CassandraOperation
|
||||
throw new IllegalArgumentException(
|
||||
String.format("Expected type String or Select; got type [%s] with value [%s]", query.getClass(), query));
|
||||
}
|
||||
|
||||
|
||||
private static class ResultSetIteratorAdapter<T> implements Iterator<T>{
|
||||
|
||||
private final Iterator<Row> iterator;
|
||||
@@ -1117,7 +1124,7 @@ public class CassandraTemplate extends CqlTemplate implements CassandraOperation
|
||||
private final CassandraConverterRowCallback<T> rowCallback;
|
||||
|
||||
public ResultSetIteratorAdapter(Iterator<Row> iterator, PersistenceExceptionTranslator exceptionTranslator, CassandraConverterRowCallback<T> rowCallback) {
|
||||
|
||||
|
||||
this.iterator = iterator;
|
||||
this.exceptionTranslator = exceptionTranslator;
|
||||
this.rowCallback = rowCallback;
|
||||
@@ -1125,7 +1132,7 @@ public class CassandraTemplate extends CqlTemplate implements CassandraOperation
|
||||
|
||||
@Override
|
||||
public boolean hasNext() {
|
||||
|
||||
|
||||
try {
|
||||
return iterator.hasNext();
|
||||
} catch (Exception e) {
|
||||
@@ -1135,7 +1142,7 @@ public class CassandraTemplate extends CqlTemplate implements CassandraOperation
|
||||
|
||||
@Override
|
||||
public T next() {
|
||||
|
||||
|
||||
try {
|
||||
return rowCallback.doWith(iterator.next());
|
||||
} catch (Exception e) {
|
||||
|
||||
@@ -104,14 +104,15 @@ public abstract class AbstractCassandraQuery implements RepositoryQuery {
|
||||
return new ResultProcessingExecution(getExecutionToWrap(accessor, resultProcessing), resultProcessing);
|
||||
}
|
||||
|
||||
private CassandraQueryExecution getExecutionToWrap(CassandraParameterAccessor accessor, Converter<Object, Object> resultProcessing) {
|
||||
private CassandraQueryExecution getExecutionToWrap(CassandraParameterAccessor accessor,
|
||||
Converter<Object, Object> resultProcessing) {
|
||||
|
||||
if (method.isResultSetQuery()) {
|
||||
if (method.isCollectionQuery()) {
|
||||
return new CollectionExecution(template);
|
||||
} else if (method.isResultSetQuery()) {
|
||||
return new ResultSetQuery(template);
|
||||
} else if (method.isStreamQuery()) {
|
||||
return new StreamExecution(template, resultProcessing);
|
||||
} else if (method.isCollectionQuery()) {
|
||||
return new CollectionExecution(template);
|
||||
} else {
|
||||
return new SingleEntityExecution(template);
|
||||
}
|
||||
|
||||
@@ -24,7 +24,6 @@ import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
@@ -184,14 +183,16 @@ public class CassandraOperationsIntegrationTests extends AbstractSpringDataEmbed
|
||||
@Test
|
||||
public void insertEmptyList() {
|
||||
List<Book> list = template.insert(new ArrayList<Book>());
|
||||
assertNotNull(list);
|
||||
assertEquals(0, list.size());
|
||||
|
||||
assertThat(list, is(notNullValue(List.class)));
|
||||
assertThat(list.isEmpty(), is(true));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void insertNullList() {
|
||||
List<Book> list = template.insert((List<Book>) null);
|
||||
assertNull(list);
|
||||
|
||||
assertThat(list, is(nullValue(List.class)));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -253,21 +254,21 @@ public class CassandraOperationsIntegrationTests extends AbstractSpringDataEmbed
|
||||
/**
|
||||
* @return
|
||||
*/
|
||||
private List<Book> getBookList(int numBooks) {
|
||||
private List<Book> getBookList(long numBooks) {
|
||||
|
||||
List<Book> books = new ArrayList<Book>();
|
||||
Book book;
|
||||
|
||||
Book b = null;
|
||||
for (int i = 0; i < numBooks; i++) {
|
||||
b = new Book();
|
||||
b.setIsbn(UUID.randomUUID().toString());
|
||||
b.setTitle("Spring Data Cassandra Guide");
|
||||
b.setAuthor("Cassandra Guru");
|
||||
b.setPages(i * 10 + 5);
|
||||
b.setInStock(true);
|
||||
b.setSaleDate(new Date());
|
||||
b.setCondition(BookCondition.NEW);
|
||||
books.add(b);
|
||||
for (int index = 0; index < numBooks; index++) {
|
||||
book = new Book();
|
||||
book.setIsbn(UUID.randomUUID().toString());
|
||||
book.setTitle("Spring Data Cassandra Guide");
|
||||
book.setAuthor("Cassandra Guru");
|
||||
book.setPages(index * 10 + 5);
|
||||
book.setInStock(true);
|
||||
book.setSaleDate(new Date());
|
||||
book.setCondition(BookCondition.NEW);
|
||||
books.add(book);
|
||||
}
|
||||
|
||||
return books;
|
||||
@@ -648,13 +649,13 @@ public class CassandraOperationsIntegrationTests extends AbstractSpringDataEmbed
|
||||
Select select = QueryBuilder.select().all().from("book");
|
||||
select.where(QueryBuilder.eq("isbn", "123456-1"));
|
||||
|
||||
Book b = template.selectOne(select, Book.class);
|
||||
Book book = template.selectOne(select, Book.class);
|
||||
|
||||
log.debug("SingleSelect Book Title -> " + b.getTitle());
|
||||
log.debug("SingleSelect Book Author -> " + b.getAuthor());
|
||||
log.debug("SingleSelect Book Title -> " + book.getTitle());
|
||||
log.debug("SingleSelect Book Author -> " + book.getAuthor());
|
||||
|
||||
assertEquals(b.getTitle(), "Spring Data Cassandra Guide");
|
||||
assertEquals(b.getAuthor(), "Cassandra Guru");
|
||||
assertThat(book.getTitle(), is(equalTo("Spring Data Cassandra Guide")));
|
||||
assertThat(book.getAuthor(), is(equalTo("Cassandra Guru")));
|
||||
|
||||
}
|
||||
|
||||
@@ -667,39 +668,39 @@ public class CassandraOperationsIntegrationTests extends AbstractSpringDataEmbed
|
||||
|
||||
Select select = QueryBuilder.select().all().from("book");
|
||||
|
||||
List<Book> bookz = template.select(select, Book.class);
|
||||
List<Book> selectedBooks = template.select(select, Book.class);
|
||||
|
||||
log.debug("Book Count -> " + bookz.size());
|
||||
log.debug("Book Count -> " + selectedBooks.size());
|
||||
|
||||
assertEquals(bookz.size(), 20);
|
||||
assertThat(selectedBooks.size(), is(equalTo(20)));
|
||||
|
||||
for (Book b : bookz) {
|
||||
Assert.assertTrue(b.isInStock());
|
||||
assertEquals(BookCondition.NEW, b.getCondition());
|
||||
for (Book book : selectedBooks) {
|
||||
assertThat(book.isInStock(), is(true));
|
||||
assertThat(book.getCondition(), is(equalTo(BookCondition.NEW)));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void selectCountTest() {
|
||||
|
||||
int count = 20;
|
||||
long count = 20;
|
||||
List<Book> books = getBookList(count);
|
||||
|
||||
template.insert(books);
|
||||
|
||||
assertEquals(count, template.count(Book.class));
|
||||
assertThat(template.count(Book.class), is(equalTo(count)));
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void insertAndSelect() {
|
||||
|
||||
int count = 20;
|
||||
long count = 20;
|
||||
List<Book> books = getBookList(count);
|
||||
|
||||
template.insert(books);
|
||||
|
||||
assertEquals(count, template.count(Book.class));
|
||||
assertThat(template.count(Book.class), is(equalTo(count)));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -708,16 +709,27 @@ public class CassandraOperationsIntegrationTests extends AbstractSpringDataEmbed
|
||||
@Test
|
||||
public void stream() {
|
||||
|
||||
List<Book> books = getBookList(20);
|
||||
template.insert(books);
|
||||
template.insert(getBookList(20));
|
||||
|
||||
Iterator<Book> iterator = template.stream("select * from book", Book.class);
|
||||
List<Book> result = new ArrayList<Book>();
|
||||
while (iterator.hasNext()) {
|
||||
result.add(iterator.next());
|
||||
Iterator<Book> iterator = template.stream("SELECT * FROM book", Book.class);
|
||||
|
||||
assertThat(iterator, is(notNullValue(Iterator.class)));
|
||||
|
||||
List<Book> selectedBooks = new ArrayList<Book>();
|
||||
|
||||
for (Book book : toIterable(iterator)) {
|
||||
selectedBooks.add(book);
|
||||
}
|
||||
|
||||
assertThat(books.size(), is(20));
|
||||
assertThat(books.get(0), is(instanceOf(Book.class)));
|
||||
assertThat(selectedBooks.size(), is(equalTo(20)));
|
||||
assertThat(selectedBooks.get(0), is(instanceOf(Book.class)));
|
||||
}
|
||||
|
||||
<T> Iterable<T> toIterable(final Iterator<T> iterator) {
|
||||
return new Iterable<T>() {
|
||||
@Override public Iterator<T> iterator() {
|
||||
return iterator;
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -278,17 +278,20 @@ public abstract class QueryIntegrationTests extends AbstractSpringDataEmbeddedCa
|
||||
@Test
|
||||
public void findOptionalShouldReturnTargetType() {
|
||||
|
||||
Person saved = new Person();
|
||||
saved.setFirstname(uuid());
|
||||
saved.setLastname(uuid());
|
||||
saved.setNumberOfChildren(1);
|
||||
Person personToSave = new Person();
|
||||
|
||||
saved = personRepository.save(saved);
|
||||
personToSave.setFirstname(uuid());
|
||||
personToSave.setLastname(uuid());
|
||||
personToSave.setNumberOfChildren(1);
|
||||
|
||||
Optional<Person> optional = personRepository.findOptionalWithLastnameAndFirstname(saved.getLastname(), saved.getFirstname());
|
||||
personToSave = personRepository.save(personToSave);
|
||||
|
||||
assertTrue(optional.isPresent());
|
||||
assertTrue(optional.get() instanceof Person);
|
||||
Optional<Person> savedPerson = personRepository.findOptionalWithLastnameAndFirstname(
|
||||
personToSave.getLastname(), personToSave.getFirstname());
|
||||
|
||||
assertThat(savedPerson, is(notNullValue(Optional.class)));
|
||||
assertThat(savedPerson.isPresent(), is(true));
|
||||
assertThat(savedPerson.get(), is(notNullValue(Person.class)));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -296,26 +299,27 @@ public abstract class QueryIntegrationTests extends AbstractSpringDataEmbeddedCa
|
||||
|
||||
Optional<Person> optional = personRepository.findOptionalWithLastnameAndFirstname("not", "existent");
|
||||
|
||||
assertFalse(optional.isPresent());
|
||||
assertThat(optional.isPresent(), is(false));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATACASS-297
|
||||
* @see <a href="DATACASS-297">https://jira.spring.io/browse/DATACASS-297</a>
|
||||
*/
|
||||
@Test
|
||||
public void streamShouldReturnEntities() {
|
||||
|
||||
for (int i = 0; i < 100; i++) {
|
||||
|
||||
Person person = new Person();
|
||||
|
||||
person.setFirstname(uuid());
|
||||
person.setLastname(uuid());
|
||||
person.setNumberOfChildren(i);
|
||||
|
||||
|
||||
personRepository.save(person);
|
||||
}
|
||||
|
||||
Stream<Person> allPeople = personRepository.findAllPeople();
|
||||
|
||||
long count = allPeople.peek(new Consumer<Person>() {
|
||||
@Override
|
||||
public void accept(Person person) {
|
||||
@@ -323,6 +327,6 @@ public abstract class QueryIntegrationTests extends AbstractSpringDataEmbeddedCa
|
||||
}
|
||||
}).count();
|
||||
|
||||
assertThat(count, is(100L));
|
||||
assertThat(count, is(equalTo(100L)));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user