DATACASS-33 - basic composite primary key support working

This commit is contained in:
Matthew Adams
2014-02-07 15:28:34 -06:00
parent 2502779445
commit 47998cea74
23 changed files with 647 additions and 172 deletions

View File

@@ -112,7 +112,8 @@ public class CassandraDataSessionFactoryBean extends CassandraSessionFactoryBean
}
}
Collection<? extends CassandraPersistentEntity<?>> entities = converter.getMappingContext().getPersistentEntities();
Collection<? extends CassandraPersistentEntity<?>> entities = converter.getMappingContext()
.getNonPrimaryKeyEntities();
for (CassandraPersistentEntity<?> entity : entities) {
admin.createTable(false, entity.getTableName(), entity.getType(), null); // TODO: allow spec of table options
@@ -135,7 +136,7 @@ public class CassandraDataSessionFactoryBean extends CassandraSessionFactoryBean
public void setConverter(CassandraConverter converter) {
Assert.notNull(converter);
this.converter = converter;
this.mappingContext = converter.getCassandraMappingContext();
this.mappingContext = converter.getMappingContext();
}
public Mapping getMapping() {

View File

@@ -29,5 +29,6 @@ import org.springframework.data.convert.EntityConverter;
public interface CassandraConverter extends
EntityConverter<CassandraPersistentEntity<?>, CassandraPersistentProperty, Object, Object> {
CassandraMappingContext getCassandraMappingContext();
@Override
CassandraMappingContext getMappingContext();
}

View File

@@ -0,0 +1,11 @@
package org.springframework.data.cassandra.convert;
import org.springframework.data.cassandra.mapping.CassandraPersistentProperty;
import org.springframework.data.mapping.model.PropertyValueProvider;
import com.datastax.driver.core.Row;
public interface CassandraRowValueProvider extends PropertyValueProvider<CassandraPersistentProperty> {
Row getRow();
}

View File

@@ -32,22 +32,23 @@ import com.datastax.driver.core.Row;
* {@link PropertyValueProvider} to read property values from a {@link Row}.
*
* @author Alex Shvid
* @author Matthew T. Adams
*/
public class CassandraPropertyValueProvider implements PropertyValueProvider<CassandraPersistentProperty> {
public class DefaultCassandraRowValueProvider implements CassandraRowValueProvider {
private static Logger log = LoggerFactory.getLogger(CassandraPropertyValueProvider.class);
private static Logger log = LoggerFactory.getLogger(DefaultCassandraRowValueProvider.class);
private final Row source;
private final SpELExpressionEvaluator evaluator;
/**
* Creates a new {@link CassandraPropertyValueProvider} with the given {@link Row} and
* Creates a new {@link DefaultCassandraRowValueProvider} with the given {@link Row} and
* {@link DefaultSpELExpressionEvaluator}.
*
* @param source must not be {@literal null}.
* @param evaluator must not be {@literal null}.
*/
public CassandraPropertyValueProvider(Row source, DefaultSpELExpressionEvaluator evaluator) {
public DefaultCassandraRowValueProvider(Row source, DefaultSpELExpressionEvaluator evaluator) {
Assert.notNull(source);
Assert.notNull(evaluator);
@@ -84,4 +85,7 @@ public class CassandraPropertyValueProvider implements PropertyValueProvider<Cas
return (T) columnType.deserialize(bytes);
}
public Row getRow() {
return source;
}
}

View File

@@ -99,11 +99,6 @@ public class MappingCassandraConverter extends AbstractCassandraConverter implem
return readEntityFromRow(persistentEntity, row);
}
@Override
public MappingContext<? extends CassandraPersistentEntity<?>, CassandraPersistentProperty> getMappingContext() {
return mappingContext;
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.applicationContext = applicationContext;
@@ -112,57 +107,81 @@ public class MappingCassandraConverter extends AbstractCassandraConverter implem
protected <S> S readEntityFromRow(final CassandraPersistentEntity<S> entity, final Row row) {
final DefaultSpELExpressionEvaluator evaluator = new DefaultSpELExpressionEvaluator(row, spELContext);
DefaultSpELExpressionEvaluator evaluator = new DefaultSpELExpressionEvaluator(row, spELContext);
final CassandraPropertyValueProvider propertyProvider = new CassandraPropertyValueProvider(row, evaluator);
DefaultCassandraRowValueProvider rowValueProvider = new DefaultCassandraRowValueProvider(row, evaluator);
CassandraPersistentEntityParameterValueProvider parameterProvider = new CassandraPersistentEntityParameterValueProvider(
entity, propertyProvider, null);
entity, rowValueProvider, null);
EntityInstantiator instantiator = instantiators.getInstantiatorFor(entity);
S instance = instantiator.createInstance(entity, parameterProvider);
final BeanWrapper<CassandraPersistentEntity<S>, S> wrapper = BeanWrapper.create(instance, conversionService);
BeanWrapper<CassandraPersistentEntity<S>, S> wrapper = BeanWrapper.create(instance, conversionService);
readPropertiesFromRow(entity, row, propertyProvider, wrapper);
readPropertiesFromRow(entity, rowValueProvider, wrapper);
return wrapper.getBean();
}
protected void readPropertiesFromRow(final CassandraPersistentEntity<?> entity, final Row row,
final CassandraPropertyValueProvider propertyProvider, final BeanWrapper<?, ?> wrapper) {
protected void readPropertiesFromRow(final CassandraPersistentEntity<?> entity,
final DefaultCassandraRowValueProvider row, final BeanWrapper<?, ?> wrapper) {
entity.doWithProperties(new PropertyHandler<CassandraPersistentProperty>() {
@Override
public void doWithPersistentProperty(CassandraPersistentProperty prop) {
MappingCassandraConverter.this.readPropertyFromRow(row, entity, prop, propertyProvider, wrapper);
MappingCassandraConverter.this.readPropertyFromRow(entity, prop, row, wrapper);
}
});
}
protected void readPropertyFromRow(final Row row, final CassandraPersistentEntity<?> entity,
final CassandraPersistentProperty prop, final CassandraPropertyValueProvider propertyProvider,
final BeanWrapper<?, ?> wrapper) {
protected void readPropertyFromRow(final CassandraPersistentEntity<?> entity, final CassandraPersistentProperty prop,
final DefaultCassandraRowValueProvider row, final BeanWrapper<?, ?> wrapper) {
if (entity.isConstructorArgument(prop)) { // skip 'cause prop was set in ctor
return;
}
if (prop.isCompositePrimaryKey()) {
readPropertiesFromRow(prop.getCompositePrimaryKeyEntity(), row, propertyProvider, wrapper);
// get the key
CassandraPersistentProperty keyProperty = entity.getIdProperty();
Object key = wrapper.getProperty(keyProperty);
if (key == null) {
key = instantiatePrimaryKey(keyProperty.getCompositePrimaryKeyEntity(), keyProperty, row);
}
// wrap the key
@SuppressWarnings("rawtypes")
BeanWrapper keyWrapper = BeanWrapper.create(key, conversionService);
// now recurse on using the key this time
readPropertiesFromRow(prop.getCompositePrimaryKeyEntity(), row, keyWrapper);
// now that the key's properties have been populated, set the key property on the entity
wrapper.setProperty(keyProperty, keyWrapper.getBean(), useFieldAccessOnly);
return;
}
if (!row.getColumnDefinitions().contains(prop.getColumnName())) {
if (!row.getRow().getColumnDefinitions().contains(prop.getColumnName())) {
return;
}
Object obj = propertyProvider.getPropertyValue(prop);
Object obj = row.getPropertyValue(prop);
wrapper.setProperty(prop, obj, useFieldAccessOnly);
}
protected Object instantiatePrimaryKey(CassandraPersistentEntity<?> entity, CassandraPersistentProperty keyProperty,
DefaultCassandraRowValueProvider propertyProvider) {
EntityInstantiator instantiator = instantiators.getInstantiatorFor(entity);
return instantiator.createInstance(entity, new CassandraPersistentEntityParameterValueProvider(entity,
propertyProvider, null));
}
public boolean getUseFieldAccessOnly() {
return useFieldAccessOnly;
}
@@ -311,7 +330,7 @@ public class MappingCassandraConverter extends AbstractCassandraConverter implem
}
@Override
public CassandraMappingContext getCassandraMappingContext() {
public CassandraMappingContext getMappingContext() {
return mappingContext;
}
}

View File

@@ -84,7 +84,7 @@ public class CassandraTemplate extends CqlTemplate implements CassandraOperation
Assert.notNull(cassandraConverter);
this.cassandraConverter = cassandraConverter;
mappingContext = cassandraConverter.getCassandraMappingContext();
mappingContext = cassandraConverter.getMappingContext();
}
@Override

View File

@@ -27,6 +27,7 @@ import org.springframework.context.expression.BeanFactoryResolver;
import org.springframework.data.cassandra.util.CassandraNamingUtils;
import org.springframework.data.mapping.Association;
import org.springframework.data.mapping.AssociationHandler;
import org.springframework.data.mapping.PersistentProperty;
import org.springframework.data.mapping.PropertyHandler;
import org.springframework.data.mapping.model.BasicPersistentEntity;
import org.springframework.data.util.TypeInformation;

View File

@@ -1,5 +1,7 @@
package org.springframework.data.cassandra.mapping;
import java.util.Collection;
import org.springframework.cassandra.core.keyspace.CreateTableSpecification;
import org.springframework.data.mapping.context.MappingContext;
import org.springframework.data.util.TypeInformation;
@@ -14,6 +16,34 @@ import com.datastax.driver.core.TableMetadata;
public interface CassandraMappingContext extends
MappingContext<CassandraPersistentEntity<?>, CassandraPersistentProperty> {
/**
* Returns only those entities that don't represent primary key types.
*
* @see #getPersistentEntities(boolean)
*/
@Override
public Collection<CassandraPersistentEntity<?>> getPersistentEntities();
/**
* Returns all persistent entities or only non-primary-key entities.
*
* @param includePrimaryKeyTypes If <code>true</code>, returns all entities, including entities that represent primary
* key types. If <code>false</code>, returns only entities that don't represent primary key types.
*/
public Collection<CassandraPersistentEntity<?>> getPersistentEntities(boolean includePrimaryKeyTypes);
/**
* Returns only those entities representing primary key types.
*/
Collection<CassandraPersistentEntity<?>> getPrimaryKeyEntities();
/**
* Returns only those entities not representing primary key types.
*
* @see #getPersistentEntities(boolean)
*/
Collection<CassandraPersistentEntity<?>> getNonPrimaryKeyEntities();
/**
* Returns a {@link CreateTableSpecification} for the given entity, including all mapping information.
*

View File

@@ -99,4 +99,7 @@ public interface CassandraPersistentProperty extends PersistentProperty<Cassandr
* @see #isClusterKeyColumn()
*/
boolean isPrimaryKeyColumn();
@Override
CassandraPersistentEntity<?> getOwner();
}

View File

@@ -19,6 +19,8 @@ import static org.springframework.cassandra.core.keyspace.CreateTableSpecificati
import java.beans.PropertyDescriptor;
import java.lang.reflect.Field;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
@@ -51,6 +53,8 @@ public class DefaultCassandraMappingContext extends
protected ApplicationContext context;
protected Map<String, Set<CassandraPersistentEntity<?>>> entitySetsByTableName = new HashMap<String, Set<CassandraPersistentEntity<?>>>();
protected Set<CassandraPersistentEntity<?>> nonPrimaryKeyEntities = new HashSet<CassandraPersistentEntity<?>>();
protected Set<CassandraPersistentEntity<?>> primaryKeyEntities = new HashSet<CassandraPersistentEntity<?>>();
/**
* Creates a new {@link DefaultCassandraMappingContext}.
@@ -59,6 +63,29 @@ public class DefaultCassandraMappingContext extends
setSimpleTypeHolder(new CassandraSimpleTypeHolder());
}
@Override
public Collection<CassandraPersistentEntity<?>> getPersistentEntities() {
return getPersistentEntities(false);
}
@Override
public Collection<CassandraPersistentEntity<?>> getPrimaryKeyEntities() {
return Collections.unmodifiableSet(primaryKeyEntities);
}
@Override
public Collection<CassandraPersistentEntity<?>> getNonPrimaryKeyEntities() {
return Collections.unmodifiableSet(nonPrimaryKeyEntities);
}
@Override
public Collection<CassandraPersistentEntity<?>> getPersistentEntities(boolean includePrimaryKeyTypes) {
if (includePrimaryKeyTypes) {
return super.getPersistentEntities();
}
return Collections.unmodifiableSet(nonPrimaryKeyEntities);
}
@Override
public CassandraPersistentProperty createPersistentProperty(Field field, PropertyDescriptor descriptor,
CassandraPersistentEntity<?> owner, SimpleTypeHolder simpleTypeHolder) {
@@ -81,6 +108,8 @@ public class DefaultCassandraMappingContext extends
entity.setApplicationContext(context);
}
// now do some caching of the entity
Set<CassandraPersistentEntity<?>> entities = entitySetsByTableName.get(entity.getTableName());
if (entities == null) {
entities = new HashSet<CassandraPersistentEntity<?>>();
@@ -88,6 +117,12 @@ public class DefaultCassandraMappingContext extends
entities.add(entity);
entitySetsByTableName.put(entity.getTableName(), entities);
if (entity.isCompositePrimaryKey()) {
primaryKeyEntities.add(entity);
} else {
nonPrimaryKeyEntities.add(entity);
}
return entity;
}

View File

@@ -15,46 +15,46 @@
*/
package org.springframework.data.cassandra.test.integration.composites;
import java.util.Date;
import java.util.Set;
import org.springframework.data.cassandra.mapping.PrimaryKey;
import org.springframework.data.cassandra.mapping.CassandraType;
import org.springframework.data.cassandra.mapping.Table;
import com.datastax.driver.core.DataType;
import org.springframework.util.Assert;
/**
* This is an example of dynamic table (wide row). PartitionKey (former RowId) is pk.author. ClusteredColumn (former
* Column Id) is pk.time
*
* @author Alex Shvid
* @author Matthew T. Adams
*/
@Table("comments")
public class Comment {
/*
* Primary Key
*/
@PrimaryKey
private CommentPK pk;
private CommentKey pk;
private String text;
@CassandraType(type = DataType.Name.SET, typeArguments = { DataType.Name.TEXT })
private Set<String> likes;
/*
* Reference to the Post
/**
* @deprecated Only for use by persistence infrastructure
*/
private String postAuthor;
private Date postTime;
@Deprecated
protected Comment() {
}
public CommentPK getPk() {
public Comment(String author, String company) {
this(new CommentKey(author, company));
}
public Comment(CommentKey pk) {
Assert.notNull(pk);
this.pk = pk;
}
public CommentKey getId() {
return pk;
}
public void setPk(CommentPK pk) {
public void setPk(CommentKey pk) {
this.pk = pk;
}
@@ -66,28 +66,30 @@ public class Comment {
this.text = text;
}
public Set<String> getLikes() {
return likes;
@Override
public boolean equals(Object that) {
if (this == that) {
return true;
}
if (that == null) {
return false;
}
if (!(that instanceof Comment)) {
return false;
}
Comment other = (Comment) that;
if (this.pk == null) {
return other.pk == null;
}
return this.pk.equals(other.pk);
}
public void setLikes(Set<String> likes) {
this.likes = likes;
@Override
public int hashCode() {
return pk.hashCode();
}
public String getPostAuthor() {
return postAuthor;
}
public void setPostAuthor(String postAuthor) {
this.postAuthor = postAuthor;
}
public Date getPostTime() {
return postTime;
}
public void setPostTime(Date postTime) {
this.postTime = postTime;
}
}

View File

@@ -0,0 +1,99 @@
/*
* Copyright 2010-2013 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.data.cassandra.test.integration.composites;
import java.io.Serializable;
import org.springframework.cassandra.core.PrimaryKeyType;
import org.springframework.data.cassandra.mapping.PrimaryKeyClass;
import org.springframework.data.cassandra.mapping.PrimaryKeyColumn;
/**
* This is an example of dynamic table (wide row) that creates each time new column with timestamp.
*
* @author Alex Shvid
* @author Matthew T. Adams
*/
@PrimaryKeyClass
public class CommentKey implements Serializable {
private static final long serialVersionUID = -7871651389236401141L;
@PrimaryKeyColumn(ordinal = 0, type = PrimaryKeyType.PARTITIONED)
private String author;
@PrimaryKeyColumn(ordinal = 1)
private String company;
/**
* @deprecated Only for use by persistence infrastructure
*/
@Deprecated
protected CommentKey() {
}
public CommentKey(String author, String company) {
setAuthor(author);
setCompany(company);
}
public String getAuthor() {
return author;
}
protected void setAuthor(String author) {
this.author = author;
}
public String getCompany() {
return company;
}
public void setCompany(String company) {
this.company = company;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((author == null) ? 0 : author.hashCode());
result = prime * result + ((company == null) ? 0 : company.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
CommentKey other = (CommentKey) obj;
if (author == null) {
if (other.author != null)
return false;
} else if (!author.equals(other.author))
return false;
if (company == null) {
if (other.company != null)
return false;
} else if (!company.equals(other.company))
return false;
return true;
}
}

View File

@@ -1,65 +0,0 @@
/*
* Copyright 2010-2013 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.data.cassandra.test.integration.composites;
import java.util.Date;
import org.springframework.cassandra.core.PrimaryKeyType;
import org.springframework.data.cassandra.mapping.PrimaryKeyClass;
import org.springframework.data.cassandra.mapping.PrimaryKeyColumn;
import org.springframework.data.cassandra.mapping.CassandraType;
import com.datastax.driver.core.DataType;
/**
* This is an example of dynamic table (wide row) that creates each time new column with timestamp.
*
* @author Alex Shvid
*/
@PrimaryKeyClass
public class CommentPK {
/*
* Row ID
*/
@PrimaryKeyColumn(ordinal = 0, type = PrimaryKeyType.PARTITIONED)
private String author;
/*
* Clustered Column
*/
@PrimaryKeyColumn(ordinal = 1)
@CassandraType(type = DataType.Name.TIMESTAMP)
private Date time;
public String getAuthor() {
return author;
}
public void setAuthor(String author) {
this.author = author;
}
public Date getTime() {
return time;
}
public void setTime(Date time) {
this.time = time;
}
}

View File

@@ -0,0 +1,6 @@
package org.springframework.data.cassandra.test.integration.composites;
import org.springframework.data.cassandra.repository.CassandraRepository;
public interface CommentRepository extends CassandraRepository<Comment, CommentKey> {
}

View File

@@ -0,0 +1,120 @@
/*
* Copyright 2011-2013 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.data.cassandra.test.integration.composites;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotSame;
import static org.junit.Assert.assertNull;
import org.springframework.data.cassandra.core.CassandraOperations;
/**
* Tests for {@link CommentRepository}.
*
* @author Matthew T. Adams
*/
public class CommentRepositoryIntegrationTests {
CommentRepository repository;
CassandraOperations template;
public CommentRepositoryIntegrationTests() {
}
public CommentRepositoryIntegrationTests(CommentRepository repository, CassandraOperations template) {
this.repository = repository;
this.template = template;
}
public void before() {
repository.deleteAll();
}
public void after() {
repository.deleteAll();
}
public void testInsert() {
String author = "testAuthorInsert";
String company = "testCompanyInsert";
Comment c = new Comment(author, company);
c.setText("testTextInsert");
CommentKey key = c.getId();
repository.save(c);
Comment retrieved = repository.findOne(key);
assertNotSame(c, retrieved);
assertEquals(c, retrieved);
assertEquals(c.getText(), retrieved.getText());
}
public void testUpdateNonKeyField() {
String author = "testAuthorUpdate";
String company = "testCompanyUpdate";
Comment c = new Comment(author, company);
c.setText("testTextUpdate");
CommentKey key = c.getId();
repository.save(c);
Comment retrieved = repository.findOne(key);
assertNotSame(c, retrieved);
assertEquals(c, retrieved);
assertEquals(c.getText(), retrieved.getText());
String newText = "x" + retrieved.getText();
retrieved.setText(newText);
repository.save(retrieved);
Comment updated = repository.findOne(key);
assertNotSame(retrieved, updated);
assertEquals(newText, updated.getText());
}
public void testDelete() {
String author = "testAuthorDelete";
String company = "testCompanyDelete";
Comment c = new Comment(author, company);
c.setText("testTextDelete");
CommentKey key = c.getId();
repository.save(c);
Comment retrieved = repository.findOne(key);
assertNotSame(c, retrieved);
assertEquals(c, retrieved);
assertEquals(c.getText(), retrieved.getText());
repository.delete(retrieved);
assertNull(repository.findOne(key));
}
}

View File

@@ -0,0 +1,110 @@
/*
* Copyright 2011-2013 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.data.cassandra.test.integration.composites;
import static org.springframework.cassandra.core.keyspace.CreateKeyspaceSpecification.createKeyspace;
import java.util.ArrayList;
import java.util.List;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cassandra.core.keyspace.CreateKeyspaceSpecification;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.cassandra.config.SchemaAction;
import org.springframework.data.cassandra.core.CassandraOperations;
import org.springframework.data.cassandra.repository.config.EnableCassandraRepositories;
import org.springframework.data.cassandra.test.integration.repository.UserRepository;
import org.springframework.data.cassandra.test.integration.support.AbstractSpringDataEmbeddedCassandraIntegrationTest;
import org.springframework.data.cassandra.test.integration.support.TestConfig;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
/**
* Base class for Java config tests for {@link UserRepository}.
*
* @author Matthew T. Adams
*/
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration
public class CommentRepositoryJavaConfigIntegrationTests extends AbstractSpringDataEmbeddedCassandraIntegrationTest {
@Configuration
@EnableCassandraRepositories(basePackageClasses = CommentRepository.class)
public static class Config extends TestConfig {
@Override
protected String getKeyspaceName() {
return CommentRepositoryJavaConfigIntegrationTests.class.getSimpleName();
}
@Override
protected List<CreateKeyspaceSpecification> getKeyspaceCreations() {
List<CreateKeyspaceSpecification> creates = new ArrayList<CreateKeyspaceSpecification>();
creates.add(createKeyspace().name(getKeyspaceName()).withSimpleReplication());
return creates;
}
@Override
public SchemaAction getSchemaAction() {
return SchemaAction.RECREATE;
}
@Override
public String getEntityBasePackage() {
return Comment.class.getPackage().getName();
}
}
@Autowired
protected CommentRepository repository;
@Autowired
protected CassandraOperations template;
CommentRepositoryIntegrationTests tests;
@Before
public void before() {
tests = new CommentRepositoryIntegrationTests(repository, template);
tests.before();
}
@After
public void after() {
tests.after();
}
@Test
public void testInsert() {
tests.testInsert();
}
@Test
public void testDelete() {
tests.testDelete();
}
@Test
public void testUpdateNonKeyField() {
tests.testUpdateNonKeyField();
}
}

View File

@@ -0,0 +1,71 @@
/*
* Copyright 2011-2013 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.data.cassandra.test.integration.composites;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.cassandra.core.CassandraOperations;
import org.springframework.data.cassandra.test.integration.repository.UserRepository;
import org.springframework.data.cassandra.test.integration.support.AbstractSpringDataEmbeddedCassandraIntegrationTest;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
/**
* Base class for xml config tests for {@link UserRepository}.
*
* @author Matthew T. Adams
*/
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration
public class CommentRepositoryXmlConfigIntegrationTests extends AbstractSpringDataEmbeddedCassandraIntegrationTest {
@Autowired
protected CommentRepository repository;
@Autowired
protected CassandraOperations template;
CommentRepositoryIntegrationTests tests;
@Before
public void setUp() throws InterruptedException {
tests = new CommentRepositoryIntegrationTests(repository, template);
tests.before();
}
@After
public void after() {
tests.after();
}
@Test
public void testInsert() {
tests.testInsert();
}
@Test
public void testDelete() {
tests.testDelete();
}
@Test
public void testUpdateNonKeyField() {
tests.testUpdateNonKeyField();
}
}

View File

@@ -34,15 +34,9 @@ import org.springframework.data.cassandra.mapping.PrimaryKeyColumn;
@PrimaryKeyClass
public class PostPK {
/*
* Row ID
*/
@PrimaryKeyColumn(ordinal = 0, type = PrimaryKeyType.PARTITIONED)
private String author;
/*
* Clustered Column
*/
@PrimaryKeyColumn(ordinal = 1)
private Date time;

View File

@@ -0,0 +1,33 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:cassandra="http://www.springframework.org/schema/data/cassandra"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="
http://www.springframework.org/schema/data/cassandra http://www.springframework.org/schema/data/cassandra/spring-cassandra-1.0.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd">
<import resource="classpath:/spring-data-cassandra-basic.xml" />
<cassandra:cluster id="cassandra-cluster"
port="${cassandra.native_transport_port}">
<cassandra:keyspace name="CommentRepositoryXmlConfigIntegrationTests"
action="CREATE" durable-writes="true">
</cassandra:keyspace>
</cassandra:cluster>
<cassandra:session id="cassandra-session"
cluster-ref="cassandra-cluster" keyspace-name="CommentRepositoryXmlConfigIntegrationTests"
cassandra-converter-ref="cassandra-converter" schema-action="CREATE">
<cassandra:mapping>
<cassandra:entity
class="org.springframework.data.cassandra.test.integration.composites.Comment">
<cassandra:table name="comments" />
</cassandra:entity>
</cassandra:mapping>
</cassandra:session>
<cassandra:repositories
base-package="org.springframework.data.cassandra.test.integration.composites" />
</beans>

View File

@@ -1,45 +1,26 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:cassandra="http://www.springframework.org/schema/data/cassandra"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:context="http://www.springframework.org/schema/context" xmlns:util="http://www.springframework.org/schema/util"
xsi:schemaLocation="
http://www.springframework.org/schema/data/cassandra http://www.springframework.org/schema/data/cassandra/spring-cassandra-1.0.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd">
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.0.xsd
">
<context:property-placeholder
location="classpath:/org/springframework/data/cassandra/test/integration/repository/cassandra.properties" />
<import resource="classpath:/spring-data-cassandra-basic.xml" />
<cassandra:cluster id="cassandra-cluster"
contact-points="${cassandra.contactPoints}" port="${cassandra.native_transport_port}">
<cassandra:local-pooling-options
min-simultaneous-requests="25" max-simultaneous-requests="100"
core-connections="2" max-connections="8" />
<cassandra:remote-pooling-options
min-simultaneous-requests="25" max-simultaneous-requests="100"
core-connections="1" max-connections="2" />
<cassandra:socket-options
connect-timeout-millis="5000" keep-alive="true" reuse-address="true"
so-linger="60" tcp-no-delay="true" receive-buffer-size="65536"
send-buffer-size="65536" />
port="${cassandra.native_transport_port}">
<cassandra:keyspace name="${cassandra.keyspace}"
<cassandra:keyspace name="UserRepositoryXmlConfigIntegrationTests"
action="CREATE" durable-writes="true">
<cassandra:replication class="SIMPLE_STRATEGY"
replication-factor="1" />
</cassandra:keyspace>
</cassandra:cluster>
<bean id="cassandra-mapping"
class="org.springframework.data.cassandra.mapping.DefaultCassandraMappingContext" />
<bean id="cassandra-converter"
class="org.springframework.data.cassandra.convert.MappingCassandraConverter">
<constructor-arg ref="cassandra-mapping" />
</bean>
<cassandra:session id="cassandra-session"
cluster-ref="cassandra-cluster" keyspace-name="${cassandra.keyspace}"
cluster-ref="cassandra-cluster" keyspace-name="UserRepositoryXmlConfigIntegrationTests"
cassandra-converter-ref="cassandra-converter" schema-action="CREATE">
<cassandra:mapping>
<cassandra:entity
@@ -49,9 +30,6 @@
</cassandra:mapping>
</cassandra:session>
<cassandra:template id="cassandra-template"
cassandra-converter-ref="cassandra-converter" session-ref="cassandra-session" />
<cassandra:repositories
base-package="org.springframework.data.cassandra.test.integration.repository" />
</beans>

View File

@@ -1,3 +0,0 @@
cassandra.contactPoints=localhost
cassandra.native_transport_port=@build.cassandra.native_transport_port@
cassandra.keyspace=UserRepositoryXmlConfigIntegrationTests

View File

@@ -0,0 +1,24 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:cassandra="http://www.springframework.org/schema/data/cassandra"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="
http://www.springframework.org/schema/data/cassandra http://www.springframework.org/schema/data/cassandra/spring-cassandra-1.0.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd">
<context:property-placeholder
location="classpath:/spring-data-cassandra-build.properties" />
<bean id="cassandra-mapping"
class="org.springframework.data.cassandra.mapping.DefaultCassandraMappingContext" />
<bean id="cassandra-converter"
class="org.springframework.data.cassandra.convert.MappingCassandraConverter">
<constructor-arg ref="cassandra-mapping" />
</bean>
<cassandra:template id="cassandra-template"
cassandra-converter-ref="cassandra-converter" session-ref="cassandra-session" />
</beans>

View File

@@ -0,0 +1 @@
cassandra.native_transport_port=@build.cassandra.native_transport_port@