From 996275188c4247026b55c9ab4b010bc1bc89a05f Mon Sep 17 00:00:00 2001 From: Mark Paluch Date: Mon, 28 Nov 2016 16:50:47 +0100 Subject: [PATCH] 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; } --- ...assandraPersistentEntitySchemaCreator.java | 10 +++--- .../mapping/BasicCassandraMappingContext.java | 18 +++++------ .../mapping/CassandraMappingContext.java | 11 +++++++ ...andraPersistentEntityMetadataVerifier.java | 32 ++----------------- ...BasicCassandraMappingContextUnitTests.java | 8 +++-- ...istentEntityMetadataVerifierUnitTests.java | 13 ++------ .../cdi/CassandraOperationsProducer.java | 16 ++++------ ...gDataEmbeddedCassandraIntegrationTest.java | 3 +- 8 files changed, 42 insertions(+), 69 deletions(-) diff --git a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/CassandraPersistentEntitySchemaCreator.java b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/CassandraPersistentEntitySchemaCreator.java index f8f234976..fad3fa723 100644 --- a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/CassandraPersistentEntitySchemaCreator.java +++ b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/CassandraPersistentEntitySchemaCreator.java @@ -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 createTableSpecifications(boolean ifNotExists) { Collection> entities = new ArrayList<>( - mappingContext.getNonPrimaryKeyEntities()); + mappingContext.getTableEntities()); List specifications = new ArrayList<>(); diff --git a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/mapping/BasicCassandraMappingContext.java b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/mapping/BasicCassandraMappingContext.java index 75aef8cb4..ee56714bb 100644 --- a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/mapping/BasicCassandraMappingContext.java +++ b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/mapping/BasicCassandraMappingContext.java @@ -79,9 +79,9 @@ public class BasicCassandraMappingContext protected Map, CassandraPersistentEntity> entitiesByType = new HashMap, CassandraPersistentEntity>(); protected Map>> entitySetsByTableName = new HashMap>>(); - protected Set> nonPrimaryKeyEntities = new HashSet>(); protected Set> primaryKeyEntities = new HashSet>(); protected Set> userDefinedTypes = new HashSet>(); + protected Set> tableEntities = new HashSet>(); private CustomConversions customConversions; @@ -128,8 +128,8 @@ public class BasicCassandraMappingContext } @Override - public Collection> getPersistentEntities() { - return getPersistentEntities(false); + public Collection> getTableEntities() { + return Collections.unmodifiableCollection(tableEntities); } @Override @@ -139,7 +139,7 @@ public class BasicCassandraMappingContext @Override public Collection> 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); } } diff --git a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/mapping/CassandraMappingContext.java b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/mapping/CassandraMappingContext.java index a89ab5b67..865074f8f 100644 --- a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/mapping/CassandraMappingContext.java +++ b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/mapping/CassandraMappingContext.java @@ -43,6 +43,13 @@ public interface CassandraMappingContext @Override Collection> getPersistentEntities(); + /** + * Returns only {@link Table} entities. + * + * @since 1.5 + */ + Collection> 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> getPrimaryKeyEntities(); /** * Returns only those entities not representing primary key types. * * @see #getPersistentEntities(boolean) + * @deprecated as of 1.5, use {@link #getTableEntities()}. */ + @Deprecated Collection> getNonPrimaryKeyEntities(); /** diff --git a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/mapping/CompositeCassandraPersistentEntityMetadataVerifier.java b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/mapping/CompositeCassandraPersistentEntityMetadataVerifier.java index 3f9002f9d..ff9dc1e62 100644 --- a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/mapping/CompositeCassandraPersistentEntityMetadataVerifier.java +++ b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/mapping/CompositeCassandraPersistentEntityMetadataVerifier.java @@ -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())))); - } - } - } } diff --git a/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/mapping/BasicCassandraMappingContextUnitTests.java b/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/mapping/BasicCassandraMappingContextUnitTests.java index e1809cef8..cfefac7e6 100755 --- a/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/mapping/BasicCassandraMappingContextUnitTests.java +++ b/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/mapping/BasicCassandraMappingContextUnitTests.java @@ -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); } /** diff --git a/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/mapping/CompositeCassandraPersistentEntityMetadataVerifierUnitTests.java b/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/mapping/CompositeCassandraPersistentEntityMetadataVerifierUnitTests.java index 586d1875d..7daca4730 100644 --- a/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/mapping/CompositeCassandraPersistentEntityMetadataVerifierUnitTests.java +++ b/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/mapping/CompositeCassandraPersistentEntityMetadataVerifierUnitTests.java @@ -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)); } /** diff --git a/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/test/integration/repository/cdi/CassandraOperationsProducer.java b/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/test/integration/repository/cdi/CassandraOperationsProducer.java index 39db3c21e..c2cab7aeb 100644 --- a/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/test/integration/repository/cdi/CassandraOperationsProducer.java +++ b/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/test/integration/repository/cdi/CassandraOperationsProducer.java @@ -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 producerToSatisfyGuavaDependenciesWhenTesting() { return Sets.newHashSet(); } - } diff --git a/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/test/integration/support/AbstractSpringDataEmbeddedCassandraIntegrationTest.java b/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/test/integration/support/AbstractSpringDataEmbeddedCassandraIntegrationTest.java index 75ef14853..110e32c0f 100755 --- a/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/test/integration/support/AbstractSpringDataEmbeddedCassandraIntegrationTest.java +++ b/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/test/integration/support/AbstractSpringDataEmbeddedCassandraIntegrationTest.java @@ -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; }