Merge branch 'DATACASS-34' of https://github.com/shvid/spring-data-cassandra
This commit is contained in:
1
pom.xml
1
pom.xml
@@ -64,6 +64,7 @@
|
||||
<name>Alex Shvid</name>
|
||||
<email>a at shvid.com</email>
|
||||
<roles>
|
||||
<role>Project Lead</role>
|
||||
<role>Developer</role>
|
||||
</roles>
|
||||
<timezone>-8</timezone>
|
||||
|
||||
@@ -28,7 +28,7 @@ import com.datastax.driver.core.TableMetadata;
|
||||
*/
|
||||
public class CassandraAdminTemplate implements CassandraAdminOperations {
|
||||
|
||||
private static Logger log = LoggerFactory.getLogger(CassandraAdminTemplate.class);
|
||||
private static final Logger log = LoggerFactory.getLogger(CassandraAdminTemplate.class);
|
||||
|
||||
private SpringDataKeyspace keyspace;
|
||||
private Session session;
|
||||
|
||||
@@ -50,6 +50,16 @@ public interface CassandraDataOperations {
|
||||
*/
|
||||
<T> List<T> select(String cql, Class<T> selectClass);
|
||||
|
||||
/**
|
||||
* Execute query and convert ResultSet to the list of entities
|
||||
*
|
||||
* @param selectQuery must not be {@literal null}.
|
||||
* @param selectClass must not be {@literal null}, mapped entity type.
|
||||
* @return
|
||||
*/
|
||||
|
||||
<T> List<T> select(Select selectQuery, Class<T> selectClass);
|
||||
|
||||
/**
|
||||
* Execute query and convert ResultSet to the entity
|
||||
*
|
||||
@@ -59,12 +69,26 @@ public interface CassandraDataOperations {
|
||||
*/
|
||||
<T> T selectOne(String cql, Class<T> selectClass);
|
||||
|
||||
<T> List<T> select(Select selectQuery, Class<T> selectClass);
|
||||
|
||||
<T> T selectOne(Select selectQuery, Class<T> selectClass);
|
||||
|
||||
/**
|
||||
* Counts rows for given query
|
||||
*
|
||||
* @param selectQuery
|
||||
* @return
|
||||
*/
|
||||
|
||||
Long count(Select selectQuery);
|
||||
|
||||
/**
|
||||
* Counts all rows for given table
|
||||
*
|
||||
* @param tableName
|
||||
* @return
|
||||
*/
|
||||
|
||||
Long count(String tableName);
|
||||
|
||||
/**
|
||||
* Insert the given object to the table by id.
|
||||
*
|
||||
|
||||
@@ -18,7 +18,6 @@ package org.springframework.data.cassandra.core;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
@@ -43,6 +42,7 @@ import com.datastax.driver.core.ResultSet;
|
||||
import com.datastax.driver.core.Row;
|
||||
import com.datastax.driver.core.Session;
|
||||
import com.datastax.driver.core.querybuilder.Batch;
|
||||
import com.datastax.driver.core.querybuilder.QueryBuilder;
|
||||
import com.datastax.driver.core.querybuilder.Select;
|
||||
|
||||
/**
|
||||
@@ -123,13 +123,22 @@ public class CassandraDataTemplate extends CassandraTemplate implements Cassandr
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.springframework.data.cassandra.core.CassandraOperations#selectCount(com.datastax.driver.core.querybuilder.Select)
|
||||
* @see org.springframework.data.cassandra.core.CassandraOperations#count(com.datastax.driver.core.querybuilder.Select)
|
||||
*/
|
||||
@Override
|
||||
public Long count(Select selectQuery) {
|
||||
return doSelectCount(selectQuery);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.springframework.data.cassandra.core.CassandraOperations#count(java.lang.String)
|
||||
*/
|
||||
@Override
|
||||
public Long count(String tableName) {
|
||||
Select select = QueryBuilder.select().countAll().from(tableName);
|
||||
return doSelectCount(select);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.springframework.data.cassandra.core.CassandraOperations#delete(java.util.List)
|
||||
*/
|
||||
@@ -165,7 +174,8 @@ public class CassandraDataTemplate extends CassandraTemplate implements Cassandr
|
||||
*/
|
||||
@Override
|
||||
public <T> void delete(List<T> entities, String tableName) {
|
||||
delete(entities, tableName, new HashMap<String, Object>());
|
||||
Map<String, Object> defaultOptions = Collections.emptyMap();
|
||||
delete(entities, tableName, defaultOptions);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
@@ -223,7 +233,8 @@ public class CassandraDataTemplate extends CassandraTemplate implements Cassandr
|
||||
*/
|
||||
@Override
|
||||
public <T> void delete(T entity, String tableName) {
|
||||
delete(entity, tableName, new HashMap<String, Object>());
|
||||
Map<String, Object> defaultOptions = Collections.emptyMap();
|
||||
delete(entity, tableName, defaultOptions);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
@@ -280,7 +291,8 @@ public class CassandraDataTemplate extends CassandraTemplate implements Cassandr
|
||||
*/
|
||||
@Override
|
||||
public <T> void deleteAsynchronously(List<T> entities, String tableName) {
|
||||
insertAsynchronously(entities, tableName, new HashMap<String, Object>());
|
||||
Map<String, Object> defaultOptions = Collections.emptyMap();
|
||||
insertAsynchronously(entities, tableName, defaultOptions);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
@@ -338,7 +350,8 @@ public class CassandraDataTemplate extends CassandraTemplate implements Cassandr
|
||||
*/
|
||||
@Override
|
||||
public <T> void deleteAsynchronously(T entity, String tableName) {
|
||||
deleteAsynchronously(entity, tableName, new HashMap<String, Object>());
|
||||
Map<String, Object> defaultOptions = Collections.emptyMap();
|
||||
deleteAsynchronously(entity, tableName, defaultOptions);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
@@ -430,7 +443,8 @@ public class CassandraDataTemplate extends CassandraTemplate implements Cassandr
|
||||
*/
|
||||
@Override
|
||||
public <T> List<T> insert(List<T> entities, String tableName) {
|
||||
return insert(entities, tableName, new HashMap<String, Object>());
|
||||
Map<String, Object> defaultOptions = Collections.emptyMap();
|
||||
return insert(entities, tableName, defaultOptions);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
@@ -488,7 +502,8 @@ public class CassandraDataTemplate extends CassandraTemplate implements Cassandr
|
||||
*/
|
||||
@Override
|
||||
public <T> T insert(T entity, String tableName) {
|
||||
return insert(entity, tableName, new HashMap<String, Object>());
|
||||
Map<String, Object> defaultOptions = Collections.emptyMap();
|
||||
return insert(entity, tableName, defaultOptions);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
@@ -545,7 +560,8 @@ public class CassandraDataTemplate extends CassandraTemplate implements Cassandr
|
||||
*/
|
||||
@Override
|
||||
public <T> List<T> insertAsynchronously(List<T> entities, String tableName) {
|
||||
return insertAsynchronously(entities, tableName, new HashMap<String, Object>());
|
||||
Map<String, Object> defaultOptions = Collections.emptyMap();
|
||||
return insertAsynchronously(entities, tableName, defaultOptions);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
@@ -603,7 +619,8 @@ public class CassandraDataTemplate extends CassandraTemplate implements Cassandr
|
||||
*/
|
||||
@Override
|
||||
public <T> T insertAsynchronously(T entity, String tableName) {
|
||||
return insertAsynchronously(entity, tableName, new HashMap<String, Object>());
|
||||
Map<String, Object> defaultOptions = Collections.emptyMap();
|
||||
return insertAsynchronously(entity, tableName, defaultOptions);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
@@ -695,7 +712,8 @@ public class CassandraDataTemplate extends CassandraTemplate implements Cassandr
|
||||
*/
|
||||
@Override
|
||||
public <T> List<T> update(List<T> entities, String tableName) {
|
||||
return update(entities, tableName, new HashMap<String, Object>());
|
||||
Map<String, Object> defaultOptions = Collections.emptyMap();
|
||||
return update(entities, tableName, defaultOptions);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
@@ -753,7 +771,8 @@ public class CassandraDataTemplate extends CassandraTemplate implements Cassandr
|
||||
*/
|
||||
@Override
|
||||
public <T> T update(T entity, String tableName) {
|
||||
return update(entity, tableName, new HashMap<String, Object>());
|
||||
Map<String, Object> defaultOptions = Collections.emptyMap();
|
||||
return update(entity, tableName, defaultOptions);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
@@ -810,7 +829,8 @@ public class CassandraDataTemplate extends CassandraTemplate implements Cassandr
|
||||
*/
|
||||
@Override
|
||||
public <T> List<T> updateAsynchronously(List<T> entities, String tableName) {
|
||||
return updateAsynchronously(entities, tableName, new HashMap<String, Object>());
|
||||
Map<String, Object> defaultOptions = Collections.emptyMap();
|
||||
return updateAsynchronously(entities, tableName, defaultOptions);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
@@ -868,7 +888,8 @@ public class CassandraDataTemplate extends CassandraTemplate implements Cassandr
|
||||
*/
|
||||
@Override
|
||||
public <T> T updateAsynchronously(T entity, String tableName) {
|
||||
return updateAsynchronously(entity, tableName, new HashMap<String, Object>());
|
||||
Map<String, Object> defaultOptions = Collections.emptyMap();
|
||||
return updateAsynchronously(entity, tableName, defaultOptions);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
@@ -968,6 +989,8 @@ public class CassandraDataTemplate extends CassandraTemplate implements Cassandr
|
||||
*/
|
||||
private <T> T doSelectOne(final String query, ReadRowCallback<T> readRowCallback) {
|
||||
|
||||
logger.info(query);
|
||||
|
||||
/*
|
||||
* Run the Query
|
||||
*/
|
||||
@@ -1183,6 +1206,7 @@ public class CassandraDataTemplate extends CassandraTemplate implements Cassandr
|
||||
try {
|
||||
|
||||
final Query q = CqlUtils.toInsertQuery(keyspace, tableName, entity, optionsByName, cassandraConverter);
|
||||
|
||||
logger.info(q.toString());
|
||||
if (q.getConsistencyLevel() != null) {
|
||||
logger.info(q.getConsistencyLevel().name());
|
||||
|
||||
@@ -0,0 +1,54 @@
|
||||
/*
|
||||
* Copyright 2012 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.repository.config;
|
||||
|
||||
import java.lang.annotation.Annotation;
|
||||
|
||||
import org.springframework.context.annotation.ImportBeanDefinitionRegistrar;
|
||||
import org.springframework.data.repository.config.RepositoryBeanDefinitionRegistrarSupport;
|
||||
import org.springframework.data.repository.config.RepositoryConfigurationExtension;
|
||||
|
||||
/**
|
||||
* {@link ImportBeanDefinitionRegistrar} to setup Cassandra repositories via {@link EnableCassandraRepositories}.
|
||||
*
|
||||
* @author Alex Shvid
|
||||
*
|
||||
*/
|
||||
public class CassandraRepositoriesRegistrar extends RepositoryBeanDefinitionRegistrarSupport {
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see org.springframework.data.repository.config.
|
||||
* RepositoryBeanDefinitionRegistrarSupport#getAnnotation()
|
||||
*/
|
||||
@Override
|
||||
protected Class<? extends Annotation> getAnnotation() {
|
||||
return EnableCassandraRepositories.class;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see org.springframework.data.repository.config.
|
||||
* RepositoryBeanDefinitionRegistrarSupport#getExtension()
|
||||
*/
|
||||
@Override
|
||||
protected RepositoryConfigurationExtension getExtension() {
|
||||
return new CassandraRepositoryConfigurationExtension();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,86 @@
|
||||
/*
|
||||
* Copyright 2012 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.repository.config;
|
||||
|
||||
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
|
||||
import org.springframework.core.annotation.AnnotationAttributes;
|
||||
import org.springframework.data.cassandra.repository.support.CassandraRepositoryFactoryBean;
|
||||
import org.springframework.data.config.ParsingUtils;
|
||||
import org.springframework.data.repository.config.AnnotationRepositoryConfigurationSource;
|
||||
import org.springframework.data.repository.config.RepositoryConfigurationExtension;
|
||||
import org.springframework.data.repository.config.RepositoryConfigurationExtensionSupport;
|
||||
import org.springframework.data.repository.config.XmlRepositoryConfigurationSource;
|
||||
import org.springframework.util.StringUtils;
|
||||
import org.w3c.dom.Element;
|
||||
|
||||
/**
|
||||
* {@link RepositoryConfigurationExtension} for Cassandra.
|
||||
*
|
||||
* @author Alex Shvid
|
||||
*
|
||||
*/
|
||||
public class CassandraRepositoryConfigurationExtension extends RepositoryConfigurationExtensionSupport {
|
||||
|
||||
private static final String CASSANDRA_DATA_TEMPLATE_REF = "cassandra-data-template-ref";
|
||||
private static final String CREATE_QUERY_INDEXES = "create-query-indexes";
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.repository.config.RepositoryConfigurationExtensionSupport#getModulePrefix()
|
||||
*/
|
||||
@Override
|
||||
protected String getModulePrefix() {
|
||||
return "cassandra";
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.repository.config.RepositoryConfigurationExtension#getRepositoryFactoryClassName()
|
||||
*/
|
||||
public String getRepositoryFactoryClassName() {
|
||||
return CassandraRepositoryFactoryBean.class.getName();
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.repository.config.RepositoryConfigurationExtensionSupport#postProcess(org.springframework.beans.factory.support.BeanDefinitionBuilder, org.springframework.data.repository.config.XmlRepositoryConfigurationSource)
|
||||
*/
|
||||
@Override
|
||||
public void postProcess(BeanDefinitionBuilder builder, XmlRepositoryConfigurationSource config) {
|
||||
|
||||
Element element = config.getElement();
|
||||
|
||||
ParsingUtils.setPropertyReference(builder, element, CASSANDRA_DATA_TEMPLATE_REF, "cassandraDataTemplate");
|
||||
ParsingUtils.setPropertyValue(builder, element, CREATE_QUERY_INDEXES, "createIndexesForQueryMethods");
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.repository.config.RepositoryConfigurationExtensionSupport#postProcess(org.springframework.beans.factory.support.BeanDefinitionBuilder, org.springframework.data.repository.config.AnnotationRepositoryConfigurationSource)
|
||||
*/
|
||||
@Override
|
||||
public void postProcess(BeanDefinitionBuilder builder, AnnotationRepositoryConfigurationSource config) {
|
||||
|
||||
AnnotationAttributes attributes = config.getAttributes();
|
||||
|
||||
String cassandraDataTemplateRef = attributes.getString("cassandraDataTemplateRef");
|
||||
if (StringUtils.hasText(cassandraDataTemplateRef)) {
|
||||
builder.addPropertyReference("cassandraDataTemplate", cassandraDataTemplateRef);
|
||||
}
|
||||
builder.addPropertyValue("createIndexesForQueryMethods", attributes.getBoolean("createIndexesForQueryMethods"));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,125 @@
|
||||
/*
|
||||
* Copyright 2012 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.repository.config;
|
||||
|
||||
import java.lang.annotation.Documented;
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Inherited;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
import org.springframework.beans.factory.FactoryBean;
|
||||
import org.springframework.context.annotation.ComponentScan.Filter;
|
||||
import org.springframework.context.annotation.Import;
|
||||
import org.springframework.data.cassandra.core.CassandraDataTemplate;
|
||||
import org.springframework.data.cassandra.repository.support.CassandraRepositoryFactoryBean;
|
||||
import org.springframework.data.repository.query.QueryLookupStrategy;
|
||||
import org.springframework.data.repository.query.QueryLookupStrategy.Key;
|
||||
|
||||
/**
|
||||
* Annotation to enable Cassandra repositories.
|
||||
*
|
||||
* @author Alex Shvid
|
||||
*
|
||||
*/
|
||||
|
||||
@Target(ElementType.TYPE)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Documented
|
||||
@Inherited
|
||||
@Import(CassandraRepositoriesRegistrar.class)
|
||||
public @interface EnableCassandraRepositories {
|
||||
|
||||
/**
|
||||
* Alias for the {@link #basePackages()} attribute. Allows for more concise annotation declarations e.g.:
|
||||
* {@code @EnableCassandraRepositories("org.my.pkg")} instead of
|
||||
* {@code @EnableCassandraRepositories(basePackages="org.my.pkg")}.
|
||||
*/
|
||||
String[] value() default {};
|
||||
|
||||
/**
|
||||
* Base packages to scan for annotated components. {@link #value()} is an alias for (and mutually exclusive with) this
|
||||
* attribute. Use {@link #basePackageClasses()} for a type-safe alternative to String-based package names.
|
||||
*/
|
||||
String[] basePackages() default {};
|
||||
|
||||
/**
|
||||
* Type-safe alternative to {@link #basePackages()} for specifying the packages to scan for annotated components. The
|
||||
* package of each class specified will be scanned. Consider creating a special no-op marker class or interface in
|
||||
* each package that serves no purpose other than being referenced by this attribute.
|
||||
*/
|
||||
Class<?>[] basePackageClasses() default {};
|
||||
|
||||
/**
|
||||
* Specifies which types are eligible for component scanning. Further narrows the set of candidate components from
|
||||
* everything in {@link #basePackages()} to everything in the base packages that matches the given filter or filters.
|
||||
*/
|
||||
Filter[] includeFilters() default {};
|
||||
|
||||
/**
|
||||
* Specifies which types are not eligible for component scanning.
|
||||
*/
|
||||
Filter[] excludeFilters() default {};
|
||||
|
||||
/**
|
||||
* Returns the postfix to be used when looking up custom repository implementations. Defaults to {@literal Impl}. So
|
||||
* for a repository named {@code UserRepository} the corresponding implementation class will be looked up scanning for
|
||||
* {@code UserRepositoryImpl}.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
String repositoryImplementationPostfix() default "Impl";
|
||||
|
||||
/**
|
||||
* Configures the location of where to find the Spring Data named queries properties file. Will default to
|
||||
* {@code META-INFO/casasndra-named-queries.properties}.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
String namedQueriesLocation() default "";
|
||||
|
||||
/**
|
||||
* Returns the key of the {@link QueryLookupStrategy} to be used for lookup queries for query methods. Defaults to
|
||||
* {@link Key#CREATE_IF_NOT_FOUND}.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
Key queryLookupStrategy() default Key.CREATE_IF_NOT_FOUND;
|
||||
|
||||
/**
|
||||
* Returns the {@link FactoryBean} class to be used for each repository instance. Defaults to
|
||||
* {@link CassandraRepositoryFactoryBean}.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
Class<?> repositoryFactoryBeanClass() default CassandraRepositoryFactoryBean.class;
|
||||
|
||||
/**
|
||||
* Configures the name of the {@link CassandraDataTemplate} bean to be used with the repositories detected.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
String cassandraDataTemplateRef() default "cassandraDataTemplate";
|
||||
|
||||
/**
|
||||
* Whether to automatically create indexes for query methods defined in the repository interface.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
boolean createIndexesForQueryMethods() default false;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
* Copyright 2011 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.repository.query;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
import org.springframework.data.repository.core.EntityInformation;
|
||||
|
||||
/**
|
||||
* Cassandra specific {@link EntityInformation}.
|
||||
*
|
||||
* @author Alex Shvid
|
||||
*
|
||||
*/
|
||||
public interface CassandraEntityInformation<T, ID extends Serializable> extends EntityInformation<T, ID> {
|
||||
|
||||
/**
|
||||
* Returns the name of the table the entity shall be persisted to.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
String getTableName();
|
||||
|
||||
/**
|
||||
* Returns the column that the id will be persisted to.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
String getIdColumn();
|
||||
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
* Copyright 2011 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.repository.query;
|
||||
|
||||
import org.springframework.data.repository.core.EntityMetadata;
|
||||
|
||||
/**
|
||||
* Extension of {@link EntityMetadata} to additionally expose the table name an entity shall be persisted to.
|
||||
*
|
||||
* @author Alex Shvid
|
||||
*
|
||||
* @param <T>
|
||||
*/
|
||||
public interface CassandraEntityMetadata<T> extends EntityMetadata<T> {
|
||||
|
||||
/**
|
||||
* Returns the name of the table the entity shall be persisted to.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
String getTableName();
|
||||
}
|
||||
@@ -0,0 +1,88 @@
|
||||
/*
|
||||
* Copyright 2010-2012 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.repository.support;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
import org.springframework.data.cassandra.core.CassandraDataTemplate;
|
||||
import org.springframework.data.cassandra.mapping.CassandraPersistentEntity;
|
||||
import org.springframework.data.cassandra.mapping.CassandraPersistentProperty;
|
||||
import org.springframework.data.cassandra.repository.CassandraRepository;
|
||||
import org.springframework.data.cassandra.repository.query.CassandraEntityInformation;
|
||||
import org.springframework.data.mapping.context.MappingContext;
|
||||
import org.springframework.data.mapping.model.MappingException;
|
||||
import org.springframework.data.repository.core.RepositoryMetadata;
|
||||
import org.springframework.data.repository.core.support.RepositoryFactorySupport;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* Factory to create {@link CassandraRepository} instances.
|
||||
*
|
||||
* @author Alex Shvid
|
||||
*
|
||||
*/
|
||||
|
||||
public class CassandraRepositoryFactory extends RepositoryFactorySupport {
|
||||
|
||||
private final CassandraDataTemplate cassandraDataTemplate;
|
||||
private final MappingContext<? extends CassandraPersistentEntity<?>, CassandraPersistentProperty> mappingContext;
|
||||
|
||||
/**
|
||||
* Creates a new {@link MongoRepositoryFactory} with the given {@link MongoOperations}.
|
||||
*
|
||||
* @param mongoOperations must not be {@literal null}
|
||||
*/
|
||||
public CassandraRepositoryFactory(CassandraDataTemplate cassandraDataTemplate) {
|
||||
|
||||
Assert.notNull(cassandraDataTemplate);
|
||||
|
||||
this.cassandraDataTemplate = cassandraDataTemplate;
|
||||
this.mappingContext = cassandraDataTemplate.getConverter().getMappingContext();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Class<?> getRepositoryBaseClass(RepositoryMetadata metadata) {
|
||||
return SimpleCassandraRepository.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings({ "rawtypes", "unchecked" })
|
||||
protected Object getTargetRepository(RepositoryMetadata metadata) {
|
||||
|
||||
CassandraEntityInformation<?, Serializable> entityInformation = getEntityInformation(metadata.getDomainType());
|
||||
|
||||
return new SimpleCassandraRepository(entityInformation, cassandraDataTemplate);
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.repository.core.support.RepositoryFactorySupport#getEntityInformation(java.lang.Class)
|
||||
*/
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public <T, ID extends Serializable> CassandraEntityInformation<T, ID> getEntityInformation(Class<T> domainClass) {
|
||||
|
||||
CassandraPersistentEntity<?> entity = mappingContext.getPersistentEntity(domainClass);
|
||||
|
||||
if (entity == null) {
|
||||
throw new MappingException(String.format("Could not lookup mapping metadata for domain class %s!",
|
||||
domainClass.getName()));
|
||||
}
|
||||
|
||||
return new MappingCassandraEntityInformation<T, ID>((CassandraPersistentEntity<T>) entity);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
/*
|
||||
* Copyright 2011 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.repository.support;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
import org.springframework.data.cassandra.core.CassandraDataTemplate;
|
||||
import org.springframework.data.cassandra.repository.CassandraRepository;
|
||||
import org.springframework.data.repository.Repository;
|
||||
import org.springframework.data.repository.core.support.RepositoryFactoryBeanSupport;
|
||||
import org.springframework.data.repository.core.support.RepositoryFactorySupport;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* {@link org.springframework.beans.factory.FactoryBean} to create {@link CassandraRepository} instances.
|
||||
*
|
||||
* @author Alex Shvid
|
||||
*
|
||||
*/
|
||||
public class CassandraRepositoryFactoryBean<T extends Repository<S, ID>, S, ID extends Serializable> extends
|
||||
RepositoryFactoryBeanSupport<T, S, ID> {
|
||||
|
||||
private CassandraDataTemplate cassandraDataTemplate;
|
||||
|
||||
@Override
|
||||
protected RepositoryFactorySupport createRepositoryFactory() {
|
||||
return new CassandraRepositoryFactory(cassandraDataTemplate);
|
||||
}
|
||||
|
||||
/**
|
||||
* Configures the {@link CassandraDataTemplate} to be used.
|
||||
*
|
||||
* @param operations the operations to set
|
||||
*/
|
||||
public void setCassandraDataTemplate(CassandraDataTemplate cassandraDataTemplate) {
|
||||
this.cassandraDataTemplate = cassandraDataTemplate;
|
||||
setMappingContext(cassandraDataTemplate.getConverter().getMappingContext());
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see
|
||||
* org.springframework.data.repository.support.RepositoryFactoryBeanSupport
|
||||
* #afterPropertiesSet()
|
||||
*/
|
||||
@Override
|
||||
public void afterPropertiesSet() {
|
||||
super.afterPropertiesSet();
|
||||
Assert.notNull(cassandraDataTemplate, "cassandraDataTemplate must not be null!");
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,107 @@
|
||||
/*
|
||||
* Copyright (c) 2011 by the original author(s).
|
||||
*
|
||||
* 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.repository.support;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
import org.springframework.data.cassandra.mapping.CassandraPersistentEntity;
|
||||
import org.springframework.data.cassandra.mapping.CassandraPersistentProperty;
|
||||
import org.springframework.data.cassandra.repository.query.CassandraEntityInformation;
|
||||
import org.springframework.data.mapping.model.BeanWrapper;
|
||||
import org.springframework.data.repository.core.support.AbstractEntityInformation;
|
||||
|
||||
/**
|
||||
* {@link CassandraEntityInformation} implementation using a {@link CassandraPersistentEntity} instance to lookup the
|
||||
* necessary information. Can be configured with a custom collection to be returned which will trump the one returned by
|
||||
* the {@link CassandraPersistentEntity} if given.
|
||||
*
|
||||
* @author Alex Shvid
|
||||
*
|
||||
*/
|
||||
public class MappingCassandraEntityInformation<T, ID extends Serializable> extends AbstractEntityInformation<T, ID>
|
||||
implements CassandraEntityInformation<T, ID> {
|
||||
|
||||
private final CassandraPersistentEntity<T> entityMetadata;
|
||||
private final String customTableName;
|
||||
|
||||
/**
|
||||
* Creates a new {@link MappingCassandraEntityInformation} for the given {@link CassandraPersistentEntity}.
|
||||
*
|
||||
* @param entity must not be {@literal null}.
|
||||
*/
|
||||
public MappingCassandraEntityInformation(CassandraPersistentEntity<T> entity) {
|
||||
this(entity, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new {@link MappingCassandraEntityInformation} for the given {@link CassandraPersistentEntity} and custom
|
||||
* table name.
|
||||
*
|
||||
* @param entity must not be {@literal null}.
|
||||
* @param customTableName
|
||||
*/
|
||||
public MappingCassandraEntityInformation(CassandraPersistentEntity<T> entity, String customTableName) {
|
||||
super(entity.getType());
|
||||
this.entityMetadata = entity;
|
||||
this.customTableName = customTableName;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.repository.support.EntityInformation#getId(java.lang.Object)
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public ID getId(T entity) {
|
||||
|
||||
CassandraPersistentProperty idProperty = entityMetadata.getIdProperty();
|
||||
|
||||
if (idProperty == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
try {
|
||||
return (ID) BeanWrapper.create(entity, null).getProperty(idProperty);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.springframework.data.repository.support.EntityInformation#getIdType()
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public Class<ID> getIdType() {
|
||||
return (Class<ID>) entityMetadata.getIdProperty().getType();
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.springframework.data.mongodb.repository.CassandraEntityInformation#getTableName()
|
||||
*/
|
||||
@Override
|
||||
public String getTableName() {
|
||||
return customTableName == null ? entityMetadata.getTable() : customTableName;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.springframework.data.mongodb.repository.CassandraEntityInformation#getIdColumn()
|
||||
*/
|
||||
public String getIdColumn() {
|
||||
return entityMetadata.getIdProperty().getName();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,237 @@
|
||||
/*
|
||||
* Copyright 2010-2012 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.repository.support;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.cassandra.core.CassandraOperations;
|
||||
import org.springframework.data.cassandra.core.CassandraDataOperations;
|
||||
import org.springframework.data.cassandra.core.CassandraDataTemplate;
|
||||
import org.springframework.data.cassandra.repository.CassandraRepository;
|
||||
import org.springframework.data.cassandra.repository.query.CassandraEntityInformation;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
import com.datastax.driver.core.querybuilder.Clause;
|
||||
import com.datastax.driver.core.querybuilder.Delete;
|
||||
import com.datastax.driver.core.querybuilder.QueryBuilder;
|
||||
import com.datastax.driver.core.querybuilder.Select;
|
||||
|
||||
/**
|
||||
* Repository base implementation for Cassandra.
|
||||
*
|
||||
* @author Alex Shvid
|
||||
*
|
||||
*/
|
||||
|
||||
public class SimpleCassandraRepository<T, ID extends Serializable> implements CassandraRepository<T, ID> {
|
||||
|
||||
private final CassandraDataTemplate cassandraDataTemplate;
|
||||
private final CassandraEntityInformation<T, ID> entityInformation;
|
||||
|
||||
/**
|
||||
* Creates a new {@link SimpleCassandraRepository} for the given {@link CassandraEntityInformation} and
|
||||
* {@link CassandraDataTemplate}.
|
||||
*
|
||||
* @param metadata must not be {@literal null}.
|
||||
* @param template must not be {@literal null}.
|
||||
*/
|
||||
public SimpleCassandraRepository(CassandraEntityInformation<T, ID> metadata,
|
||||
CassandraDataTemplate cassandraDataTemplate) {
|
||||
|
||||
Assert.notNull(cassandraDataTemplate);
|
||||
Assert.notNull(metadata);
|
||||
|
||||
this.entityInformation = metadata;
|
||||
this.cassandraDataTemplate = cassandraDataTemplate;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.repository.CrudRepository#save(java.lang.Object)
|
||||
*/
|
||||
public <S extends T> S save(S entity) {
|
||||
|
||||
Assert.notNull(entity, "Entity must not be null!");
|
||||
cassandraDataTemplate.insert(entity, entityInformation.getTableName());
|
||||
return entity;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.repository.CrudRepository#save(java.lang.Iterable)
|
||||
*/
|
||||
public <S extends T> List<S> save(Iterable<S> entities) {
|
||||
|
||||
Assert.notNull(entities, "The given Iterable of entities not be null!");
|
||||
|
||||
List<S> result = new ArrayList<S>();
|
||||
|
||||
for (S entity : entities) {
|
||||
save(entity);
|
||||
result.add(entity);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private Clause getIdClause(ID id) {
|
||||
Clause clause = QueryBuilder.eq(entityInformation.getIdColumn(), id);
|
||||
return clause;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.repository.CrudRepository#findOne(java.io.Serializable)
|
||||
*/
|
||||
public T findOne(ID id) {
|
||||
Assert.notNull(id, "The given id must not be null!");
|
||||
|
||||
Select select = QueryBuilder.select().all().from(entityInformation.getTableName());
|
||||
select.where(getIdClause(id));
|
||||
|
||||
return cassandraDataTemplate.selectOne(select, entityInformation.getJavaType());
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.repository.CrudRepository#exists(java.io.Serializable)
|
||||
*/
|
||||
public boolean exists(ID id) {
|
||||
|
||||
Assert.notNull(id, "The given id must not be null!");
|
||||
|
||||
Select select = QueryBuilder.select().countAll().from(entityInformation.getTableName());
|
||||
select.where(getIdClause(id));
|
||||
|
||||
Long num = cassandraDataTemplate.count(select);
|
||||
return num != null && num.longValue() > 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.repository.CrudRepository#count()
|
||||
*/
|
||||
public long count() {
|
||||
return cassandraDataTemplate.count(entityInformation.getTableName());
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.repository.CrudRepository#delete(java.io.Serializable)
|
||||
*/
|
||||
public void delete(ID id) {
|
||||
Assert.notNull(id, "The given id must not be null!");
|
||||
|
||||
Delete delete = QueryBuilder.delete().all().from(entityInformation.getTableName());
|
||||
delete.where(getIdClause(id));
|
||||
|
||||
cassandraDataTemplate.execute(delete.getQueryString());
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.repository.CrudRepository#delete(java.lang.Object)
|
||||
*/
|
||||
public void delete(T entity) {
|
||||
Assert.notNull(entity, "The given entity must not be null!");
|
||||
delete(entityInformation.getId(entity));
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.repository.CrudRepository#delete(java.lang.Iterable)
|
||||
*/
|
||||
public void delete(Iterable<? extends T> entities) {
|
||||
|
||||
Assert.notNull(entities, "The given Iterable of entities not be null!");
|
||||
|
||||
for (T entity : entities) {
|
||||
delete(entity);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.repository.CrudRepository#deleteAll()
|
||||
*/
|
||||
public void deleteAll() {
|
||||
cassandraDataTemplate.truncate(entityInformation.getTableName());
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.repository.CrudRepository#findAll()
|
||||
*/
|
||||
public List<T> findAll() {
|
||||
Select select = QueryBuilder.select().all().from(entityInformation.getTableName());
|
||||
return findAll(select);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.repository.CrudRepository#findAll(java.lang.Iterable)
|
||||
*/
|
||||
public Iterable<T> findAll(Iterable<ID> ids) {
|
||||
|
||||
List<ID> parameters = new ArrayList<ID>();
|
||||
for (ID id : ids) {
|
||||
parameters.add(id);
|
||||
}
|
||||
Clause clause = QueryBuilder.in(entityInformation.getIdColumn(), parameters.toArray());
|
||||
Select select = QueryBuilder.select().all().from(entityInformation.getTableName());
|
||||
select.where(clause);
|
||||
|
||||
return findAll(select);
|
||||
}
|
||||
|
||||
private List<T> findAll(Select query) {
|
||||
|
||||
if (query == null) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
return cassandraDataTemplate.select(query, entityInformation.getJavaType());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the underlying {@link CassandraOperations} instance.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
protected CassandraOperations getCassandraOperations() {
|
||||
return this.cassandraDataTemplate;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the underlying {@link CassandraDataOperations} instance.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
protected CassandraDataOperations getCassandraDataOperations() {
|
||||
return this.cassandraDataTemplate;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the entityInformation
|
||||
*/
|
||||
protected CassandraEntityInformation<T, ID> getEntityInformation() {
|
||||
return entityInformation;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
/*
|
||||
* Copyright 2011 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.repository;
|
||||
|
||||
import org.springframework.data.cassandra.repository.CassandraRepository;
|
||||
import org.springframework.data.cassandra.test.integration.table.User;
|
||||
|
||||
/**
|
||||
* Sample repository managing {@link User} entities.
|
||||
*
|
||||
* @author Alex Shvid
|
||||
*
|
||||
*/
|
||||
public interface UserRepository extends CassandraRepository<User, String> {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,168 @@
|
||||
/*
|
||||
* 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.repository;
|
||||
|
||||
import static org.hamcrest.Matchers.hasItem;
|
||||
import static org.hamcrest.Matchers.hasItems;
|
||||
import static org.hamcrest.Matchers.is;
|
||||
import static org.hamcrest.Matchers.not;
|
||||
import static org.junit.Assert.assertThat;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.cassandra.exceptions.ConfigurationException;
|
||||
import org.apache.thrift.transport.TTransportException;
|
||||
import org.cassandraunit.utils.EmbeddedCassandraServerHelper;
|
||||
import org.junit.AfterClass;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Before;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.data.cassandra.core.CassandraDataOperations;
|
||||
import org.springframework.data.cassandra.test.integration.table.User;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
|
||||
/**
|
||||
* Base class for tests for {@link UserRepository}.
|
||||
*
|
||||
* @author Alex Shvid
|
||||
*
|
||||
*/
|
||||
@ContextConfiguration
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
public class UserRepositoryIntegrationTests {
|
||||
|
||||
@Autowired
|
||||
protected UserRepository repository;
|
||||
|
||||
@Autowired
|
||||
protected CassandraDataOperations dataOperations;
|
||||
|
||||
User tom, bob, alice, scott;
|
||||
|
||||
List<User> all;
|
||||
|
||||
@BeforeClass
|
||||
public static void startCassandra() throws IOException, TTransportException, ConfigurationException,
|
||||
InterruptedException {
|
||||
EmbeddedCassandraServerHelper.startEmbeddedCassandra("cassandra.yaml");
|
||||
}
|
||||
|
||||
@Before
|
||||
public void setUp() throws InterruptedException {
|
||||
|
||||
repository.deleteAll();
|
||||
|
||||
tom = new User();
|
||||
tom.setUsername("tom");
|
||||
tom.setFirstName("Tom");
|
||||
tom.setLastName("Ron");
|
||||
tom.setPassword("123");
|
||||
tom.setPlace("SF");
|
||||
|
||||
bob = new User();
|
||||
bob.setUsername("bob");
|
||||
bob.setFirstName("Bob");
|
||||
bob.setLastName("White");
|
||||
bob.setPassword("555");
|
||||
bob.setPlace("NY");
|
||||
|
||||
alice = new User();
|
||||
alice.setUsername("alice");
|
||||
alice.setFirstName("Alice");
|
||||
alice.setLastName("Red");
|
||||
alice.setPassword("777");
|
||||
alice.setPlace("LA");
|
||||
|
||||
scott = new User();
|
||||
scott.setUsername("scott");
|
||||
scott.setFirstName("Scott");
|
||||
scott.setLastName("Van");
|
||||
scott.setPassword("444");
|
||||
scott.setPlace("Boston");
|
||||
|
||||
all = dataOperations.insert(Arrays.asList(tom, bob, alice, scott));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void findsUserById() throws Exception {
|
||||
|
||||
User user = repository.findOne(bob.getUsername());
|
||||
Assert.assertNotNull(user);
|
||||
assertEquals(bob, user);
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void findsAll() throws Exception {
|
||||
List<User> result = Lists.newArrayList(repository.findAll());
|
||||
assertThat(result.size(), is(all.size()));
|
||||
assertThat(result.containsAll(all), is(true));
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void findsAllWithGivenIds() {
|
||||
|
||||
Iterable<User> result = repository.findAll(Arrays.asList(bob.getUsername(), tom.getUsername()));
|
||||
assertThat(result, hasItems(bob, tom));
|
||||
assertThat(result, not(hasItems(alice, scott)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void deletesUserCorrectly() throws Exception {
|
||||
|
||||
repository.delete(tom);
|
||||
|
||||
List<User> result = Lists.newArrayList(repository.findAll());
|
||||
|
||||
assertThat(result.size(), is(all.size() - 1));
|
||||
assertThat(result, not(hasItem(tom)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void deletesUserByIdCorrectly() {
|
||||
|
||||
repository.delete(tom.getUsername().toString());
|
||||
|
||||
List<User> result = Lists.newArrayList(repository.findAll());
|
||||
|
||||
assertThat(result.size(), is(all.size() - 1));
|
||||
assertThat(result, not(hasItem(tom)));
|
||||
}
|
||||
|
||||
@AfterClass
|
||||
public static void stopCassandra() {
|
||||
EmbeddedCassandraServerHelper.cleanEmbeddedCassandra();
|
||||
EmbeddedCassandraServerHelper.stopEmbeddedCassandra();
|
||||
}
|
||||
|
||||
private static void assertEquals(User user1, User user2) {
|
||||
Assert.assertEquals(user1.getUsername(), user2.getUsername());
|
||||
Assert.assertEquals(user1.getFirstName(), user2.getFirstName());
|
||||
Assert.assertEquals(user1.getLastName(), user2.getLastName());
|
||||
Assert.assertEquals(user1.getPlace(), user2.getPlace());
|
||||
Assert.assertEquals(user1.getPassword(), user2.getPassword());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -22,7 +22,7 @@ import org.springframework.data.cassandra.mapping.Index;
|
||||
import org.springframework.data.cassandra.mapping.Table;
|
||||
|
||||
/**
|
||||
* This is an example of the Users statis table, where all fields are columns in Cassandra row. Some fields can be
|
||||
* This is an example of the Users status table, where all fields are columns in Cassandra row. Some fields can be
|
||||
* Set,List,Map like emails.
|
||||
*
|
||||
* User contains base information related for separate user, like names, additional information, emails, following
|
||||
@@ -63,9 +63,9 @@ public class User {
|
||||
private String password;
|
||||
|
||||
/*
|
||||
* Age
|
||||
* Birth Year
|
||||
*/
|
||||
private int age;
|
||||
private int birthYear;
|
||||
|
||||
/*
|
||||
* Following other users in userline
|
||||
@@ -142,17 +142,42 @@ public class User {
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Returns the age.
|
||||
* @return Returns the birthYear.
|
||||
*/
|
||||
public int getAge() {
|
||||
return age;
|
||||
public int getBirthYear() {
|
||||
return birthYear;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param age The age to set.
|
||||
* @param birthYear The birthYear to set.
|
||||
*/
|
||||
public void setAge(int age) {
|
||||
this.age = age;
|
||||
public void setBirthYear(int birthYear) {
|
||||
this.birthYear = birthYear;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
int result = 1;
|
||||
result = prime * result + ((username == null) ? 0 : username.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;
|
||||
User other = (User) obj;
|
||||
if (username == null) {
|
||||
if (other.username != null)
|
||||
return false;
|
||||
} else if (!username.equals(other.username))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<beans xmlns="http://java.sun.com/xml/ns/javaee"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/beans_1_0.xsd">
|
||||
</beans>
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
User.findByNamedQuery=SELECT firstName FROM table WHERE firstName=?0
|
||||
@@ -0,0 +1,75 @@
|
||||
<?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: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/util http://www.springframework.org/schema/util/spring-util.xsd">
|
||||
|
||||
<context:property-placeholder
|
||||
location="classpath:/org/springframework/data/cassandra/test/integration/repository/cassandra.properties" />
|
||||
|
||||
<cassandra:cluster id="cassandra-cluster"
|
||||
contactPoints="${cassandra.contactPoints}" port="${cassandra.port}"
|
||||
compression="SNAPPY">
|
||||
<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-mls="5000" keep-alive="true" reuse-address="true"
|
||||
so-linger="60" tcp-no-delay="true" receive-buffer-size="65536"
|
||||
send-buffer-size="65536" />
|
||||
</cassandra:cluster>
|
||||
|
||||
<bean id="cassandra-mapping"
|
||||
class=" org.springframework.data.cassandra.mapping.CassandraMappingContext" />
|
||||
|
||||
<bean id="cassandra-converter"
|
||||
class=" org.springframework.data.cassandra.convert.MappingCassandraConverter">
|
||||
<constructor-arg ref="cassandra-mapping" />
|
||||
</bean>
|
||||
|
||||
<cassandra:keyspace id="cassandra-keyspace" name="${cassandra.keyspace}"
|
||||
cassandra-cluster-ref="cassandra-cluster" cassandra-converter-ref="cassandra-converter">
|
||||
<cassandra:keyspace-attributes auto="update"
|
||||
replication-stategy="SimpleStrategy" replication-factor="1"
|
||||
durable-writes="true">
|
||||
<cassandra:table entity="org.springframework.data.cassandra.test.integration.table.Comment" />
|
||||
<cassandra:table
|
||||
entity="org.springframework.data.cassandra.test.integration.table.Notification" />
|
||||
<cassandra:table entity="org.springframework.data.cassandra.test.integration.table.Post" />
|
||||
<cassandra:table entity="org.springframework.data.cassandra.test.integration.table.Timeline" />
|
||||
<cassandra:table entity="org.springframework.data.cassandra.test.integration.table.User" />
|
||||
</cassandra:keyspace-attributes>
|
||||
</cassandra:keyspace>
|
||||
|
||||
<cassandra:session id="cassandra-session" cassandra-keyspace-ref="cassandra-keyspace"/>
|
||||
|
||||
<bean id="cassandraTemplate" class="org.springframework.cassandra.core.CassandraTemplate">
|
||||
<constructor-arg ref="cassandra-session" />
|
||||
</bean>
|
||||
|
||||
<bean id="cassandraDataTemplate" class="org.springframework.data.cassandra.core.CassandraDataTemplate">
|
||||
<constructor-arg ref="cassandra-session" />
|
||||
<constructor-arg ref="cassandra-converter" />
|
||||
<constructor-arg value="${cassandra.keyspace}" />
|
||||
</bean>
|
||||
|
||||
<bean class="org.springframework.data.cassandra.repository.support.CassandraRepositoryFactoryBean">
|
||||
<property name="cassandraDataTemplate" ref="cassandraDataTemplate"/>
|
||||
<property name="repositoryInterface" value="org.springframework.data.cassandra.test.integration.repository.UserRepository"/>
|
||||
<property name="namedQueries">
|
||||
<bean class="org.springframework.data.repository.core.support.PropertiesBasedNamedQueries">
|
||||
<constructor-arg>
|
||||
<util:properties location="classpath:/META-INF/cassandra-named-queries.properties" />
|
||||
</constructor-arg>
|
||||
</bean>
|
||||
</property>
|
||||
</bean>
|
||||
|
||||
</beans>
|
||||
@@ -0,0 +1,7 @@
|
||||
cassandra.contactPoints=localhost
|
||||
cassandra.port=9042
|
||||
cassandra.keyspace=TestKS123
|
||||
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user