DATACASS-360 - Do not require @Table annotation.
We no longer require entities to be annotated with @Table for data mapping and CRUD operations.
Entities without @Table can be still mapped in both directions and will be excluded from schema-management to prevent table creation for unwanted classes.
A class annotated with @Table will participate in schema management and be exposed as a table entity. Classes used as entities without @Table can still be used to query Cassandra but schema management will not create any tables for these classes.
@Table // entity qualified for schema management
class Person {
@Id private String id;
private String lastname;
private String firstname;
}
// entity that can be used for
// select/insert/update/delete operations and repository use
class Person {
@Id private String id;
private String lastname;
private String firstname;
}
This commit is contained in:
@@ -25,6 +25,10 @@ import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import com.datastax.driver.core.KeyspaceMetadata;
|
||||
import com.datastax.driver.core.TableMetadata;
|
||||
import com.datastax.driver.core.UserType;
|
||||
|
||||
import org.springframework.cassandra.core.cql.CqlIdentifier;
|
||||
import org.springframework.cassandra.core.cql.generator.CreateTableCqlGenerator;
|
||||
import org.springframework.cassandra.core.cql.generator.CreateUserTypeCqlGenerator;
|
||||
@@ -36,10 +40,6 @@ import org.springframework.data.cassandra.mapping.CassandraPersistentProperty;
|
||||
import org.springframework.data.mapping.PropertyHandler;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
import com.datastax.driver.core.KeyspaceMetadata;
|
||||
import com.datastax.driver.core.TableMetadata;
|
||||
import com.datastax.driver.core.UserType;
|
||||
|
||||
/**
|
||||
* Schema creation support for Cassandra based on {@link CassandraMappingContext} and {@link CassandraPersistentEntity}.
|
||||
* This class generates CQL to drop, recreate and create user types (UDT) and tables.
|
||||
@@ -149,7 +149,7 @@ public class CassandraPersistentEntitySchemaCreator {
|
||||
protected List<CreateTableSpecification> createTableSpecifications(boolean ifNotExists) {
|
||||
|
||||
Collection<? extends CassandraPersistentEntity<?>> entities = new ArrayList<>(
|
||||
mappingContext.getNonPrimaryKeyEntities());
|
||||
mappingContext.getTableEntities());
|
||||
|
||||
List<CreateTableSpecification> specifications = new ArrayList<>();
|
||||
|
||||
|
||||
@@ -79,9 +79,9 @@ public class BasicCassandraMappingContext
|
||||
protected Map<Class<?>, CassandraPersistentEntity<?>> entitiesByType = new HashMap<Class<?>, CassandraPersistentEntity<?>>();
|
||||
protected Map<CqlIdentifier, Set<CassandraPersistentEntity<?>>> entitySetsByTableName = new HashMap<CqlIdentifier, Set<CassandraPersistentEntity<?>>>();
|
||||
|
||||
protected Set<CassandraPersistentEntity<?>> nonPrimaryKeyEntities = new HashSet<CassandraPersistentEntity<?>>();
|
||||
protected Set<CassandraPersistentEntity<?>> primaryKeyEntities = new HashSet<CassandraPersistentEntity<?>>();
|
||||
protected Set<CassandraPersistentEntity<?>> userDefinedTypes = new HashSet<CassandraPersistentEntity<?>>();
|
||||
protected Set<CassandraPersistentEntity<?>> tableEntities = new HashSet<CassandraPersistentEntity<?>>();
|
||||
|
||||
private CustomConversions customConversions;
|
||||
|
||||
@@ -128,8 +128,8 @@ public class BasicCassandraMappingContext
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<CassandraPersistentEntity<?>> getPersistentEntities() {
|
||||
return getPersistentEntities(false);
|
||||
public Collection<CassandraPersistentEntity<?>> getTableEntities() {
|
||||
return Collections.unmodifiableCollection(tableEntities);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -139,7 +139,7 @@ public class BasicCassandraMappingContext
|
||||
|
||||
@Override
|
||||
public Collection<CassandraPersistentEntity<?>> getNonPrimaryKeyEntities() {
|
||||
return Collections.unmodifiableSet(nonPrimaryKeyEntities);
|
||||
return getTableEntities();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -158,7 +158,7 @@ public class BasicCassandraMappingContext
|
||||
return super.getPersistentEntities();
|
||||
}
|
||||
|
||||
return Collections.unmodifiableSet(nonPrimaryKeyEntities);
|
||||
return getTableEntities();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -207,10 +207,10 @@ public class BasicCassandraMappingContext
|
||||
if (!entity.isUserDefinedType()) {
|
||||
if (entity.isCompositePrimaryKey()) {
|
||||
primaryKeyEntities.add(entity);
|
||||
} else {
|
||||
if (entity.findAnnotation(Persistent.class) != null) {
|
||||
nonPrimaryKeyEntities.add(entity);
|
||||
}
|
||||
}
|
||||
|
||||
if (entity.findAnnotation(Table.class) != null) {
|
||||
tableEntities.add(entity);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -43,6 +43,13 @@ public interface CassandraMappingContext
|
||||
@Override
|
||||
Collection<CassandraPersistentEntity<?>> getPersistentEntities();
|
||||
|
||||
/**
|
||||
* Returns only {@link Table} entities.
|
||||
*
|
||||
* @since 1.5
|
||||
*/
|
||||
Collection<CassandraPersistentEntity<?>> getTableEntities();
|
||||
|
||||
/**
|
||||
* Returns all persistent entities or only non-primary-key entities.
|
||||
*
|
||||
@@ -53,14 +60,18 @@ public interface CassandraMappingContext
|
||||
|
||||
/**
|
||||
* Returns only those entities representing primary key types.
|
||||
* @deprecated as of 1.5
|
||||
*/
|
||||
@Deprecated
|
||||
Collection<CassandraPersistentEntity<?>> getPrimaryKeyEntities();
|
||||
|
||||
/**
|
||||
* Returns only those entities not representing primary key types.
|
||||
*
|
||||
* @see #getPersistentEntities(boolean)
|
||||
* @deprecated as of 1.5, use {@link #getTableEntities()}.
|
||||
*/
|
||||
@Deprecated
|
||||
Collection<CassandraPersistentEntity<?>> getNonPrimaryKeyEntities();
|
||||
|
||||
/**
|
||||
|
||||
@@ -17,9 +17,7 @@ package org.springframework.data.cassandra.mapping;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
|
||||
import org.springframework.data.annotation.Persistent;
|
||||
import org.springframework.data.mapping.model.MappingException;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
@@ -43,8 +41,8 @@ public class CompositeCassandraPersistentEntityMetadataVerifier implements Cassa
|
||||
* @see PrimaryKeyClassEntityMetadataVerifier
|
||||
*/
|
||||
public CompositeCassandraPersistentEntityMetadataVerifier() {
|
||||
this(Arrays.asList(new PersistentAnnotationVerifier(), new PrimaryKeyClassEntityMetadataVerifier(),
|
||||
new BasicCassandraPersistentEntityMetadataVerifier()));
|
||||
this(Arrays.asList(new PrimaryKeyClassEntityMetadataVerifier(),
|
||||
new BasicCassandraPersistentEntityMetadataVerifier()));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -70,30 +68,4 @@ public class CompositeCassandraPersistentEntityMetadataVerifier implements Cassa
|
||||
verifier.verify(entity);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@link CassandraPersistentEntityMetadataVerifier} implementation that requires classes to be annotated with
|
||||
* {@link Persistent}, {@link Table} or {@link PrimaryKeyClass}.
|
||||
*
|
||||
* @author Mark Paluch
|
||||
*/
|
||||
private static class PersistentAnnotationVerifier implements CassandraPersistentEntityMetadataVerifier {
|
||||
|
||||
@Override
|
||||
public void verify(CassandraPersistentEntity<?> entity) throws MappingException {
|
||||
|
||||
if (entity.getType().isInterface()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Ensure entity is either a @Table/@Persistent, @UserDefinedType or a @PrimaryKey
|
||||
if (entity.findAnnotation(Persistent.class) == null && entity.findAnnotation(UserDefinedType.class) == null) {
|
||||
throw new VerifierMappingExceptions(entity,
|
||||
Collections.singletonList(new MappingException(
|
||||
String.format("Cassandra entities must be annotated with either @%s, @%s, @%s or @%s",
|
||||
Persistent.class.getSimpleName(), Table.class.getSimpleName(),
|
||||
UserDefinedType.class.getSimpleName(), PrimaryKeyClass.class.getSimpleName()))));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -66,7 +66,7 @@ public class BasicCassandraMappingContextUnitTests {
|
||||
});
|
||||
}
|
||||
|
||||
@Test(expected = MappingException.class)
|
||||
@Test
|
||||
public void testGetPersistentEntityOfTransientType() {
|
||||
mappingContext.getPersistentEntity(Transient.class);
|
||||
}
|
||||
@@ -392,11 +392,11 @@ public class BasicCassandraMappingContextUnitTests {
|
||||
|
||||
CassandraPersistentEntity<?> existingPersistentEntity = mappingContext.getPersistentEntity(MappedUdt.class);
|
||||
|
||||
assertThat(mappingContext.getNonPrimaryKeyEntities()).doesNotContain(existingPersistentEntity);
|
||||
assertThat(mappingContext.getTableEntities()).doesNotContain(existingPersistentEntity);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATACASS-172
|
||||
* @see DATACASS-172, DATACASS-359
|
||||
*/
|
||||
@Test
|
||||
public void getPersistentEntitiesShouldContainUdt() {
|
||||
@@ -404,7 +404,9 @@ public class BasicCassandraMappingContextUnitTests {
|
||||
CassandraPersistentEntity<?> existingPersistentEntity = mappingContext.getPersistentEntity(MappedUdt.class);
|
||||
|
||||
assertThat(mappingContext.getPersistentEntities(true)).contains(existingPersistentEntity);
|
||||
assertThat(mappingContext.getUserDefinedTypeEntities()).contains(existingPersistentEntity);
|
||||
assertThat(mappingContext.getPersistentEntities(false)).doesNotContain(existingPersistentEntity);
|
||||
assertThat(mappingContext.getTableEntities()).doesNotContain(existingPersistentEntity);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -65,18 +65,11 @@ public class CompositeCassandraPersistentEntityMetadataVerifierUnitTests {
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATACASS-258
|
||||
* @see DATACASS-258, DATACASS-359
|
||||
*/
|
||||
@Test
|
||||
public void shouldFailWithNonPersistentClasses() {
|
||||
|
||||
try {
|
||||
verifier.verify(getEntity(NonPersistentClass.class));
|
||||
fail("Missing MappingException");
|
||||
} catch (MappingException e) {
|
||||
assertThat(e).hasMessageContaining(
|
||||
"Cassandra entities must be annotated with either @Persistent, @Table, @UserDefinedType or @PrimaryKeyClass");
|
||||
}
|
||||
public void shouldNotFailWithNonPersistentClasses() {
|
||||
verifier.verify(getEntity(NonPersistentClass.class));
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -17,13 +17,15 @@ package org.springframework.data.cassandra.test.integration.repository.cdi;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.enterprise.context.ApplicationScoped;
|
||||
import javax.enterprise.inject.Disposes;
|
||||
import javax.enterprise.inject.Produces;
|
||||
import javax.inject.Singleton;
|
||||
|
||||
import org.springframework.cassandra.core.cql.CqlIdentifier;
|
||||
import com.datastax.driver.core.Cluster;
|
||||
import com.google.common.collect.Sets;
|
||||
import com.google.common.util.concurrent.Service;
|
||||
|
||||
import org.springframework.cassandra.core.cql.generator.CreateKeyspaceCqlGenerator;
|
||||
import org.springframework.cassandra.core.cql.generator.DropKeyspaceCqlGenerator;
|
||||
import org.springframework.cassandra.core.keyspace.CreateKeyspaceSpecification;
|
||||
@@ -39,10 +41,6 @@ import org.springframework.data.cassandra.mapping.CassandraPersistentEntity;
|
||||
import org.springframework.data.cassandra.mapping.SimpleUserTypeResolver;
|
||||
import org.springframework.data.cassandra.test.integration.repository.simple.User;
|
||||
|
||||
import com.datastax.driver.core.Cluster;
|
||||
import com.google.common.collect.Sets;
|
||||
import com.google.common.util.concurrent.Service;
|
||||
|
||||
/**
|
||||
* @author Mark Paluch
|
||||
*/
|
||||
@@ -55,9 +53,8 @@ class CassandraOperationsProducer {
|
||||
public Cluster createCluster() throws Exception {
|
||||
CassandraConnectionProperties properties = new CassandraConnectionProperties();
|
||||
|
||||
Cluster cluster = Cluster.builder().addContactPoint(properties.getCassandraHost())
|
||||
return Cluster.builder().addContactPoint(properties.getCassandraHost())
|
||||
.withPort(properties.getCassandraPort()).build();
|
||||
return cluster;
|
||||
}
|
||||
|
||||
@Produces
|
||||
@@ -83,7 +80,7 @@ class CassandraOperationsProducer {
|
||||
schemaCreator.createTables(false, false, true);
|
||||
|
||||
for (CassandraPersistentEntity<?> entity : cassandraTemplate.getConverter().getMappingContext()
|
||||
.getPersistentEntities()) {
|
||||
.getTableEntities()) {
|
||||
cassandraTemplate.truncate(entity.getType());
|
||||
}
|
||||
|
||||
@@ -112,5 +109,4 @@ class CassandraOperationsProducer {
|
||||
public Set<Service> producerToSatisfyGuavaDependenciesWhenTesting() {
|
||||
return Sets.newHashSet();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -39,8 +39,7 @@ public abstract class AbstractSpringDataEmbeddedCassandraIntegrationTest
|
||||
*/
|
||||
public void deleteAllEntities() {
|
||||
|
||||
for (CassandraPersistentEntity<?> entity : template.getConverter().getMappingContext().getPersistentEntities()) {
|
||||
|
||||
for (CassandraPersistentEntity<?> entity : template.getConverter().getMappingContext().getTableEntities()) {
|
||||
if (entity.getType().isInterface()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user