DATACASS-33 - basic composite primary key support working
This commit is contained in:
@@ -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() {
|
||||
|
||||
@@ -29,5 +29,6 @@ import org.springframework.data.convert.EntityConverter;
|
||||
public interface CassandraConverter extends
|
||||
EntityConverter<CassandraPersistentEntity<?>, CassandraPersistentProperty, Object, Object> {
|
||||
|
||||
CassandraMappingContext getCassandraMappingContext();
|
||||
@Override
|
||||
CassandraMappingContext getMappingContext();
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -84,7 +84,7 @@ public class CassandraTemplate extends CqlTemplate implements CassandraOperation
|
||||
Assert.notNull(cassandraConverter);
|
||||
|
||||
this.cassandraConverter = cassandraConverter;
|
||||
mappingContext = cassandraConverter.getCassandraMappingContext();
|
||||
mappingContext = cassandraConverter.getMappingContext();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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.
|
||||
*
|
||||
|
||||
@@ -99,4 +99,7 @@ public interface CassandraPersistentProperty extends PersistentProperty<Cassandr
|
||||
* @see #isClusterKeyColumn()
|
||||
*/
|
||||
boolean isPrimaryKeyColumn();
|
||||
|
||||
@Override
|
||||
CassandraPersistentEntity<?> getOwner();
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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> {
|
||||
}
|
||||
@@ -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));
|
||||
}
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
cassandra.contactPoints=localhost
|
||||
cassandra.native_transport_port=@build.cassandra.native_transport_port@
|
||||
cassandra.keyspace=UserRepositoryXmlConfigIntegrationTests
|
||||
@@ -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>
|
||||
@@ -0,0 +1 @@
|
||||
cassandra.native_transport_port=@build.cassandra.native_transport_port@
|
||||
Reference in New Issue
Block a user