DATACASS-286 - Log all CQL queries executed with CqlTemplate.
Additional refactoring to simplify CqlTemplate logic as well as make CqlTemplate methods more behaviorally consistent. Origina pull request: #61.
This commit is contained in:
@@ -31,6 +31,7 @@ import org.springframework.cassandra.core.keyspace.DropIndexSpecification;
|
||||
import org.springframework.cassandra.core.keyspace.DropKeyspaceSpecification;
|
||||
import org.springframework.cassandra.core.keyspace.DropTableSpecification;
|
||||
import org.springframework.dao.DataAccessException;
|
||||
import org.springframework.dao.IncorrectResultSizeDataAccessException;
|
||||
|
||||
import com.datastax.driver.core.PreparedStatement;
|
||||
import com.datastax.driver.core.ResultSet;
|
||||
@@ -693,14 +694,17 @@ public interface CqlOperations {
|
||||
<T> T queryForObject(Select select, RowMapper<T> rowMapper) throws DataAccessException;
|
||||
|
||||
/**
|
||||
* Process a ResultSet through a RowMapper. This is used internal to the Template for core operations, but is made
|
||||
* available through Operations in the event you have a ResultSet to process. The ResultsSet could come from a
|
||||
* ResultSetFuture after an asynchronous query.
|
||||
*
|
||||
* @param resultSet
|
||||
* @param rowMapper
|
||||
* @return
|
||||
* @throws DataAccessException
|
||||
* Process {@link ResultSet} with {@link RowMapper}. This method is used internally to the template
|
||||
* for core operations, but is made available through this interface in the event you have a {@link ResultSet}
|
||||
* to process. The {@link ResultSet} could come from a {@link ResultSetFuture} after an asynchronous query.
|
||||
*
|
||||
* @param resultSet {@link ResultSet} to process.
|
||||
* @param rowMapper {@link RowMapper} used to process the single row of the result set.
|
||||
* @throws IllegalArgumentException if {@link ResultSet} is null.
|
||||
* @throws IncorrectResultSizeDataAccessException if no rows are found, or more than 1 row is found.
|
||||
* @throws DataAccessException if a Cassandra driver error occurs.
|
||||
* @see org.springframework.cassandra.core.RowMapper
|
||||
* @see com.datastax.driver.core.ResultSet
|
||||
*/
|
||||
<T> T processOne(ResultSet resultSet, RowMapper<T> rowMapper) throws DataAccessException;
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -23,70 +23,84 @@ import org.springframework.util.Assert;
|
||||
import com.datastax.driver.core.Session;
|
||||
|
||||
/**
|
||||
* A {@link CassandraAccessor} is able to access a Cassandra {@link Session} and the
|
||||
* {@link CassandraExceptionTranslator}.
|
||||
* {@link CassandraAccessor} provides access to a Cassandra {@link Session} and the {@link CassandraExceptionTranslator}
|
||||
* .
|
||||
* <p>
|
||||
* Classes providing a higher abstraction level usually extend {@link CassandraAccessor} to provide a richer set of
|
||||
* functionality on top of a {@link Session}.
|
||||
*
|
||||
* @author David Webb
|
||||
* @author Mark Paluch
|
||||
* @author John Blum
|
||||
* @see org.springframework.beans.factory.InitializingBean
|
||||
* @see com.datastax.driver.core.Session
|
||||
*/
|
||||
public class CassandraAccessor implements InitializingBean {
|
||||
|
||||
/** Logger available to subclasses */
|
||||
CassandraExceptionTranslator exceptionTranslator = new CassandraExceptionTranslator();
|
||||
|
||||
protected final Logger logger = LoggerFactory.getLogger(getClass());
|
||||
|
||||
private Session session;
|
||||
private CassandraExceptionTranslator exceptionTranslator = new CassandraExceptionTranslator();
|
||||
|
||||
/**
|
||||
* Ensure that the Cassandra Session has been set
|
||||
* Ensures the Cassandra {@link Session} and exception translator has been propertly set.
|
||||
*/
|
||||
@Override
|
||||
public void afterPropertiesSet() {
|
||||
Assert.state(session != null, "Session must not be null");
|
||||
}
|
||||
|
||||
Assert.notNull(session, "Session must not be null!");
|
||||
Assert.notNull(exceptionTranslator, "CassandraExceptionTranslator must not be null!");
|
||||
/* (non-Javadoc) */
|
||||
protected void logDebug(String logMessage, Object... array) {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug(logMessage, array);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the exception translator for this instance.
|
||||
* Sets the exception translator used by this template to translate Cassandra specific Exceptions into Spring DAO's
|
||||
* Exception Hierarchy.
|
||||
*
|
||||
* @param exceptionTranslator the exception translator to set, must not be {@literal null}.
|
||||
* @param exceptionTranslator exception translator to set; must not be {@literal null}.
|
||||
* @see org.springframework.cassandra.support.CassandraExceptionTranslator
|
||||
*/
|
||||
public void setExceptionTranslator(CassandraExceptionTranslator exceptionTranslator) {
|
||||
|
||||
Assert.notNull(exceptionTranslator, "CassandraExceptionTranslator must not be null!");
|
||||
Assert.notNull(exceptionTranslator, "CassandraExceptionTranslator must not be null");
|
||||
this.exceptionTranslator = exceptionTranslator;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the exception translator for this instance.
|
||||
* Return the exception translator used by this template to translate Cassandra specific Exceptions into Spring DAO's
|
||||
* Exception Hierarchy.
|
||||
*
|
||||
* @return the exception translator
|
||||
* @return the Cassandra exception translator.
|
||||
* @see org.springframework.cassandra.support.CassandraExceptionTranslator
|
||||
*/
|
||||
public CassandraExceptionTranslator getExceptionTranslator() {
|
||||
Assert.state(this.exceptionTranslator != null, "CassandraExceptionTranslator was not properly initialized");
|
||||
return this.exceptionTranslator;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the session.
|
||||
* Sets the Cassandra {@link Session} used by this template to perform Cassandra data access operations.
|
||||
*
|
||||
* @return the session.
|
||||
* @param session Cassandra {@link Session} used by this template. Must not be{@literal null}.
|
||||
* @see com.datastax.driver.core.Session
|
||||
*/
|
||||
public Session getSession() {
|
||||
return session;
|
||||
public void setSession(Session session) {
|
||||
Assert.notNull(session, "Session must not be null");
|
||||
this.session = session;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param session The session to set, must not be{@literal null}
|
||||
* Returns the Cassandra {@link Session} used by this template to perform Cassandra data access operations.
|
||||
*
|
||||
* @return the Cassandra {@link Session} used by this template.
|
||||
* @see com.datastax.driver.core.Session
|
||||
*/
|
||||
public void setSession(Session session) {
|
||||
|
||||
Assert.notNull(session, "Session must not be null!");
|
||||
this.session = session;
|
||||
public Session getSession() {
|
||||
Assert.state(this.session != null, "Session was not properly initialized");
|
||||
return this.session;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,267 @@
|
||||
/*
|
||||
* Copyright 2013-2016 the original author or authors
|
||||
*
|
||||
* 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 org.springframework.cassandra.core;
|
||||
|
||||
import static org.hamcrest.Matchers.*;
|
||||
import static org.junit.Assert.*;
|
||||
import static org.mockito.Mockito.*;
|
||||
|
||||
import java.util.Iterator;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.rules.ExpectedException;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.runners.MockitoJUnitRunner;
|
||||
import org.springframework.dao.IncorrectResultSizeDataAccessException;
|
||||
|
||||
import com.datastax.driver.core.ColumnDefinitions;
|
||||
import com.datastax.driver.core.ResultSet;
|
||||
import com.datastax.driver.core.Row;
|
||||
import com.datastax.driver.core.Session;
|
||||
|
||||
/**
|
||||
* The CqlTemplateUnitTests class is a test suite of test cases testing the contract and functionality of the
|
||||
* {@link CqlTemplate} class.
|
||||
*
|
||||
* @author John Blum
|
||||
* @see org.springframework.cassandra.core.CqlTemplate
|
||||
* @since 1.5.0
|
||||
*/
|
||||
// TODO: add many more unit tests until SUT test coverage is 100%!
|
||||
@RunWith(MockitoJUnitRunner.class)
|
||||
public class CqlTemplateUnitTests {
|
||||
|
||||
@Rule public ExpectedException exception = ExpectedException.none();
|
||||
|
||||
private CqlTemplate template;
|
||||
|
||||
@Mock private Session mockSession;
|
||||
|
||||
@Before
|
||||
public void setup() {
|
||||
template = new CqlTemplate(mockSession);
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("unchecked")
|
||||
public void firstColumnToObjectReturnsColumnValue() {
|
||||
final Row mockRow = mock(Row.class);
|
||||
ColumnDefinitions mockColumnDefinitions = mock(ColumnDefinitions.class);
|
||||
Iterator<ColumnDefinitions.Definition> mockIterator = mock(Iterator.class);
|
||||
final ColumnDefinitions.Definition mockColumnDefinition = mock(ColumnDefinitions.Definition.class);
|
||||
|
||||
when(mockRow.getColumnDefinitions()).thenReturn(mockColumnDefinitions);
|
||||
when(mockColumnDefinitions.iterator()).thenReturn(mockIterator);
|
||||
when(mockIterator.hasNext()).thenReturn(true);
|
||||
when(mockIterator.next()).thenReturn(mockColumnDefinition);
|
||||
|
||||
template = new CqlTemplate() {
|
||||
@Override
|
||||
<T> T columnToObject(Row row, ColumnDefinitions.Definition columnDefinition) {
|
||||
assertThat(row, is(sameInstance(mockRow)));
|
||||
assertThat(columnDefinition, is(sameInstance(mockColumnDefinition)));
|
||||
return (T) "test";
|
||||
}
|
||||
};
|
||||
|
||||
assertThat(String.valueOf(template.firstColumnToObject(mockRow)), is(equalTo("test")));
|
||||
|
||||
verify(mockRow, times(1)).getColumnDefinitions();
|
||||
verify(mockColumnDefinitions, times(1)).iterator();
|
||||
verify(mockIterator, times(1)).hasNext();
|
||||
verify(mockIterator, times(1)).next();
|
||||
verifyZeroInteractions(mockColumnDefinition);
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("unchecked")
|
||||
public void firstColumnToObjectReturnsNull() {
|
||||
Row mockRow = mock(Row.class);
|
||||
ColumnDefinitions mockColumnDefinitions = mock(ColumnDefinitions.class);
|
||||
Iterator<ColumnDefinitions.Definition> mockIterator = mock(Iterator.class);
|
||||
|
||||
when(mockRow.getColumnDefinitions()).thenReturn(mockColumnDefinitions);
|
||||
when(mockColumnDefinitions.iterator()).thenReturn(mockIterator);
|
||||
when(mockIterator.hasNext()).thenReturn(false);
|
||||
|
||||
assertThat(template.firstColumnToObject(mockRow), is(nullValue(Object.class)));
|
||||
|
||||
verify(mockRow, times(1)).getColumnDefinitions();
|
||||
verify(mockColumnDefinitions, times(1)).iterator();
|
||||
verify(mockIterator, times(1)).hasNext();
|
||||
verify(mockIterator, never()).next();
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("unchecked")
|
||||
public void processOneIsSuccessful() {
|
||||
ResultSet mockResultSet = mock(ResultSet.class);
|
||||
Row mockRow = mock(Row.class);
|
||||
RowMapper<String> mockRowMapper = mock(RowMapper.class);
|
||||
|
||||
when(mockResultSet.one()).thenReturn(mockRow);
|
||||
when(mockResultSet.isExhausted()).thenReturn(true);
|
||||
when(mockRowMapper.mapRow(eq(mockRow), eq(0))).thenReturn("test");
|
||||
|
||||
assertThat(template.processOne(mockResultSet, mockRowMapper), is(equalTo("test")));
|
||||
|
||||
verify(mockResultSet, times(1)).one();
|
||||
verify(mockResultSet, times(1)).isExhausted();
|
||||
verify(mockRowMapper, times(1)).mapRow(eq(mockRow), eq(0));
|
||||
verifyZeroInteractions(mockRow);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void processOneThrowsIncorrectResultSetSizeDataAccessExceptionWhenNoRowsFound() {
|
||||
ResultSet mockResultSet = mock(ResultSet.class);
|
||||
RowMapper mockRowMapper = mock(RowMapper.class);
|
||||
|
||||
when(mockResultSet.one()).thenReturn(null);
|
||||
|
||||
try {
|
||||
exception.expect(IncorrectResultSizeDataAccessException.class);
|
||||
exception.expectCause(is(nullValue(Throwable.class)));
|
||||
exception.expectMessage(containsString("expected 1, actual 0"));
|
||||
|
||||
template.processOne(mockResultSet, mockRowMapper);
|
||||
|
||||
} finally {
|
||||
verify(mockResultSet, times(1)).one();
|
||||
verify(mockResultSet, never()).isExhausted();
|
||||
verifyZeroInteractions(mockRowMapper);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void processOneThrowsIncorrectResultSetSizeDataAccessExceptionWhenTooManyRowsFound() {
|
||||
ResultSet mockResultSet = mock(ResultSet.class);
|
||||
Row mockRow = mock(Row.class);
|
||||
RowMapper mockRowMapper = mock(RowMapper.class);
|
||||
|
||||
when(mockResultSet.one()).thenReturn(mockRow);
|
||||
when(mockResultSet.isExhausted()).thenReturn(false);
|
||||
|
||||
try {
|
||||
exception.expect(IncorrectResultSizeDataAccessException.class);
|
||||
exception.expectCause(is(nullValue(Throwable.class)));
|
||||
exception.expectMessage("ResultSet size exceeds 1");
|
||||
|
||||
template.processOne(mockResultSet, mockRowMapper);
|
||||
|
||||
} finally {
|
||||
verify(mockResultSet, times(1)).one();
|
||||
verify(mockResultSet, times(1)).isExhausted();
|
||||
verifyZeroInteractions(mockRowMapper);
|
||||
verifyZeroInteractions(mockRow);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void processOnePassingNullResultSetThrowsIllegalArgumentException() {
|
||||
RowMapper mockRowMapper = mock(RowMapper.class);
|
||||
|
||||
try {
|
||||
exception.expect(IllegalArgumentException.class);
|
||||
exception.expectCause(is(nullValue(Throwable.class)));
|
||||
exception.expectMessage("ResultSet cannot be null");
|
||||
|
||||
template.processOne(null, mockRowMapper);
|
||||
} finally {
|
||||
verifyZeroInteractions(mockRowMapper);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("unchecked")
|
||||
public void processOneWithRequiredTypeIsSuccessful() {
|
||||
ResultSet mockResultSet = mock(ResultSet.class);
|
||||
final Row mockRow = mock(Row.class);
|
||||
|
||||
when(mockResultSet.one()).thenReturn(mockRow);
|
||||
when(mockResultSet.isExhausted()).thenReturn(true);
|
||||
|
||||
template = new CqlTemplate() {
|
||||
@Override
|
||||
protected Object firstColumnToObject(Row row) {
|
||||
assertThat(row, is(equalTo(mockRow)));
|
||||
return 1l;
|
||||
}
|
||||
};
|
||||
|
||||
Number value = template.processOne(mockResultSet, Long.class);
|
||||
|
||||
assertThat(value, is(instanceOf(Long.class)));
|
||||
assertThat(value.longValue(), is(equalTo(1l)));
|
||||
|
||||
verify(mockResultSet, times(1)).one();
|
||||
verify(mockResultSet, times(1)).isExhausted();
|
||||
verifyZeroInteractions(mockRow);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void processOneWithRequiredTypeThrowsIncorrectResultSetSizeDataAccessExceptionWhenNoRowsFound() {
|
||||
ResultSet mockResultSet = mock(ResultSet.class);
|
||||
|
||||
when(mockResultSet.one()).thenReturn(null);
|
||||
|
||||
try {
|
||||
exception.expect(IncorrectResultSizeDataAccessException.class);
|
||||
exception.expectCause(is(nullValue(Throwable.class)));
|
||||
exception.expectMessage(containsString("expected 1, actual 0"));
|
||||
|
||||
template.processOne(mockResultSet, Integer.class);
|
||||
|
||||
} finally {
|
||||
verify(mockResultSet, times(1)).one();
|
||||
verify(mockResultSet, never()).isExhausted();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void processOneWithRequiredTypeThrowsIncorrectResultSetSizeDataAccessExceptionWhenTooManyRowsFound() {
|
||||
ResultSet mockResultSet = mock(ResultSet.class);
|
||||
Row mockRow = mock(Row.class);
|
||||
|
||||
when(mockResultSet.one()).thenReturn(mockRow);
|
||||
when(mockResultSet.isExhausted()).thenReturn(false);
|
||||
|
||||
try {
|
||||
exception.expect(IncorrectResultSizeDataAccessException.class);
|
||||
exception.expectCause(is(nullValue(Throwable.class)));
|
||||
exception.expectMessage(containsString("ResultSet size exceeds 1"));
|
||||
|
||||
template.processOne(mockResultSet, Double.class);
|
||||
|
||||
} finally {
|
||||
verify(mockResultSet, times(1)).one();
|
||||
verify(mockResultSet, times(1)).isExhausted();
|
||||
verifyZeroInteractions(mockRow);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void processOneWithRequiredTypePassingNullResultSetThrowsIllegalArgumentException() {
|
||||
exception.expect(IllegalArgumentException.class);
|
||||
exception.expectCause(is(nullValue(Throwable.class)));
|
||||
exception.expectMessage(is(equalTo("ResultSet cannot be null")));
|
||||
|
||||
template.processOne(null, String.class);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,108 @@
|
||||
/*
|
||||
* Copyright 2013-2016 the original author or authors
|
||||
*
|
||||
* 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 org.springframework.cassandra.support;
|
||||
|
||||
import static org.hamcrest.Matchers.*;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.rules.ExpectedException;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.runners.MockitoJUnitRunner;
|
||||
|
||||
import com.datastax.driver.core.Session;
|
||||
|
||||
/**
|
||||
* The CassandraAccessorUnitTests class is a test suite of test cases testing the contract and functionality of the
|
||||
* {@link CassandraAccessor} class.
|
||||
*
|
||||
* @author John Blum
|
||||
* @see org.springframework.cassandra.support.CassandraAccessor
|
||||
* @since 1.5.0
|
||||
*/
|
||||
@RunWith(MockitoJUnitRunner.class)
|
||||
public class CassandraAccessorUnitTests {
|
||||
|
||||
private CassandraAccessor cassandraAccessor;
|
||||
|
||||
@Mock private CassandraExceptionTranslator mockExceptionTranslator;
|
||||
|
||||
@Rule public ExpectedException exception = ExpectedException.none();
|
||||
|
||||
@Mock private Session mockSession;
|
||||
|
||||
@Before
|
||||
public void setup() {
|
||||
cassandraAccessor = new CassandraAccessor();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void afterPropertiesSetWithUnitializedSessionThrowsIllegalStateException() {
|
||||
exception.expect(IllegalStateException.class);
|
||||
exception.expectCause(is(nullValue(Throwable.class)));
|
||||
exception.expectMessage("Session must not be null");
|
||||
|
||||
cassandraAccessor.afterPropertiesSet();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void setAndGetExceptionTranslator() {
|
||||
cassandraAccessor.setExceptionTranslator(mockExceptionTranslator);
|
||||
assertThat(cassandraAccessor.getExceptionTranslator(), is(sameInstance(mockExceptionTranslator)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void setExceptionTranslatorToNullThrowsIllegalArgumentException() {
|
||||
exception.expect(IllegalArgumentException.class);
|
||||
exception.expectCause(is(nullValue(Throwable.class)));
|
||||
exception.expectMessage(is(equalTo("CassandraExceptionTranslator must not be null")));
|
||||
|
||||
cassandraAccessor.setExceptionTranslator(null);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getUninitializedExceptionTranslatorReturnsDefault() {
|
||||
assertThat(cassandraAccessor.getExceptionTranslator(), is(equalTo(cassandraAccessor.exceptionTranslator)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void setAndGetSession() {
|
||||
cassandraAccessor.setSession(mockSession);
|
||||
assertThat(cassandraAccessor.getSession(), is(sameInstance(mockSession)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void setSessionToNullThrowsIllegalArgumentException() {
|
||||
exception.expect(IllegalArgumentException.class);
|
||||
exception.expectCause(is(nullValue(Throwable.class)));
|
||||
exception.expectMessage(is(equalTo("Session must not be null")));
|
||||
|
||||
cassandraAccessor.setSession(null);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getUninitializedSessionThrowsIllegalStateException() {
|
||||
exception.expect(IllegalStateException.class);
|
||||
exception.expectCause(is(nullValue(Throwable.class)));
|
||||
exception.expectMessage(is(equalTo("Session was not properly initialized")));
|
||||
|
||||
cassandraAccessor.getSession();
|
||||
}
|
||||
}
|
||||
@@ -49,6 +49,7 @@ import org.springframework.cassandra.core.WriteOptions;
|
||||
import org.springframework.cassandra.core.keyspace.CreateTableSpecification;
|
||||
import org.springframework.cassandra.test.integration.AbstractKeyspaceCreatingIntegrationTest;
|
||||
import org.springframework.dao.DataAccessException;
|
||||
import org.springframework.dao.IncorrectResultSizeDataAccessException;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
|
||||
import com.datastax.driver.core.BoundStatement;
|
||||
@@ -607,19 +608,18 @@ public class CqlOperationsIntegrationTests extends AbstractKeyspaceCreatingInteg
|
||||
/**
|
||||
* Test that CQL for QueryForObject must only return 1 row or an IllegalArgumentException is thrown.
|
||||
*/
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
@Test(expected = IncorrectResultSizeDataAccessException.class)
|
||||
public void queryForObjectTestCqlStringRowMapperNotOneRowReturned() {
|
||||
|
||||
// Insert our 3 test books.
|
||||
insertTestObjectArray();
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
Book book = cqlTemplate.queryForObject("select * from book where isbn in ('1234','2345','3456')",
|
||||
Book book = cqlTemplate.queryForObject("SELECT * FROM book WHERE isbn IN('1234','2345','3456')",
|
||||
new RowMapper<Book>() {
|
||||
@Override
|
||||
public Book mapRow(Row row, int rowNum) throws DriverException {
|
||||
Book b = rowToBook(row);
|
||||
return b;
|
||||
return rowToBook(row);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -17,8 +17,8 @@ package org.springframework.data.cassandra.core;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.cassandra.core.CqlOperations;
|
||||
import org.springframework.cassandra.core.Cancellable;
|
||||
import org.springframework.cassandra.core.CqlOperations;
|
||||
import org.springframework.cassandra.core.QueryForObjectListener;
|
||||
import org.springframework.cassandra.core.QueryOptions;
|
||||
import org.springframework.cassandra.core.WriteOptions;
|
||||
|
||||
@@ -97,11 +97,16 @@ public class CassandraTemplate extends CqlTemplate implements CassandraOperation
|
||||
*/
|
||||
public CassandraTemplate(Session session, CassandraConverter converter) {
|
||||
setSession(session);
|
||||
setConverter(converter != null ? converter : getDefaultCassandraConverter());
|
||||
setConverter(resolveConverter(converter));
|
||||
}
|
||||
|
||||
private static CassandraConverter getDefaultCassandraConverter() {
|
||||
/* (non-Javadoc) */
|
||||
private static CassandraConverter resolveConverter(CassandraConverter cassandraConverter) {
|
||||
return (cassandraConverter != null ? cassandraConverter : getDefaultCassandraConverter());
|
||||
}
|
||||
|
||||
/* (non-Javadoc) */
|
||||
private static CassandraConverter getDefaultCassandraConverter() {
|
||||
MappingCassandraConverter mappingCassandraConverter = new MappingCassandraConverter();
|
||||
mappingCassandraConverter.afterPropertiesSet();
|
||||
return mappingCassandraConverter;
|
||||
@@ -110,8 +115,8 @@ public class CassandraTemplate extends CqlTemplate implements CassandraOperation
|
||||
/**
|
||||
* Set the {@link CassandraConverter} used by this template to perform conversions.
|
||||
*
|
||||
* @param cassandraConverter Converter used to perform conversion of Cassandra data types to entity types.
|
||||
* Must not be {@literal null}.
|
||||
* @param cassandraConverter Converter used to perform conversion of Cassandra data types to entity types. Must not be
|
||||
* {@literal null}.
|
||||
*/
|
||||
public void setConverter(CassandraConverter cassandraConverter) {
|
||||
|
||||
@@ -146,8 +151,8 @@ public class CassandraTemplate extends CqlTemplate implements CassandraOperation
|
||||
|
||||
super.afterPropertiesSet();
|
||||
|
||||
Assert.notNull(cassandraConverter, "CassandraConverter must not be null!");
|
||||
Assert.notNull(mappingContext, "CassandraMappingContext must not be null!");
|
||||
Assert.notNull(cassandraConverter, "CassandraConverter must not be null");
|
||||
Assert.notNull(mappingContext, "CassandraMappingContext must not be null");
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
Reference in New Issue
Block a user