diff --git a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/convert/DefaultCassandraRowValueProvider.java b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/convert/DefaultCassandraRowValueProvider.java index 342bc8193..051745621 100644 --- a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/convert/DefaultCassandraRowValueProvider.java +++ b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/convert/DefaultCassandraRowValueProvider.java @@ -66,8 +66,8 @@ public class DefaultCassandraRowValueProvider implements CassandraRowValueProvid return evaluator.evaluate(expression); } - String columnName = property.getColumnName(); - if (source.isNull(property.getColumnName())) { + String columnName = property.getColumnName().toCql(); + if (source.isNull(columnName)) { return null; } @@ -133,6 +133,7 @@ public class DefaultCassandraRowValueProvider implements CassandraRowValueProvid return (T) source.getBytes(columnName); } + @Override public Row getRow() { return source; } diff --git a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/convert/MappingCassandraConverter.java b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/convert/MappingCassandraConverter.java index 56d102099..9da230a43 100644 --- a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/convert/MappingCassandraConverter.java +++ b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/convert/MappingCassandraConverter.java @@ -165,7 +165,7 @@ public class MappingCassandraConverter extends AbstractCassandraConverter implem return; } - if (!row.getRow().getColumnDefinitions().contains(prop.getColumnName())) { + if (!row.getRow().getColumnDefinitions().contains(prop.getColumnName().toCql())) { return; } @@ -246,7 +246,7 @@ public class MappingCassandraConverter extends AbstractCassandraConverter implem } if (value != null) { - insert.value(prop.getColumnName(), value); + insert.value(prop.getColumnName().toCql(), value); } } }); @@ -276,9 +276,9 @@ public class MappingCassandraConverter extends AbstractCassandraConverter implem if (value != null) { if (prop.isIdProperty() || entity.isCompositePrimaryKey()) { - update.where(QueryBuilder.eq(prop.getColumnName(), value)); + update.where(QueryBuilder.eq(prop.getColumnName().toCql(), value)); } else { - update.with(QueryBuilder.set(prop.getColumnName(), value)); + update.with(QueryBuilder.set(prop.getColumnName().toCql(), value)); } } } @@ -309,7 +309,7 @@ public class MappingCassandraConverter extends AbstractCassandraConverter implem return; } - where.and(QueryBuilder.eq(idProperty.getColumnName(), idValue)); + where.and(QueryBuilder.eq(idProperty.getColumnName().toCql(), idValue)); } @SuppressWarnings("unchecked") diff --git a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/CassandraTemplate.java b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/CassandraTemplate.java index 53bd0df1b..21cd70616 100644 --- a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/CassandraTemplate.java +++ b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/CassandraTemplate.java @@ -262,7 +262,7 @@ public class CassandraTemplate extends CqlTemplate implements CassandraOperation } Select select = QueryBuilder.select().all().from(entity.getTableName().toCql()); - select.where(QueryBuilder.in(entity.getIdProperty().getColumnName(), CollectionUtils.toArray(ids))); + select.where(QueryBuilder.in(entity.getIdProperty().getColumnName().toCql(), CollectionUtils.toArray(ids))); return select(select.getQueryString(), type); } @@ -304,7 +304,7 @@ public class CassandraTemplate extends CqlTemplate implements CassandraOperation @Override public void doWithPersistentProperty(CassandraPersistentProperty p) { - clauseCallback.doWithClause(QueryBuilder.eq(p.getColumnName(), + clauseCallback.doWithClause(QueryBuilder.eq(p.getColumnName().toCql(), idWrapper.getProperty(p, p.getActualType(), useFieldAccessOnly))); } }); @@ -312,7 +312,7 @@ public class CassandraTemplate extends CqlTemplate implements CassandraOperation return; } - clauseCallback.doWithClause(QueryBuilder.eq(idProperty.getColumnName(), id)); + clauseCallback.doWithClause(QueryBuilder.eq(idProperty.getColumnName().toCql(), id)); } protected void appendIdCriteria(final com.datastax.driver.core.querybuilder.Select.Where where, diff --git a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/mapping/BasicCassandraPersistentEntity.java b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/mapping/BasicCassandraPersistentEntity.java index 22cfce2ac..9ffe79aad 100644 --- a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/mapping/BasicCassandraPersistentEntity.java +++ b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/mapping/BasicCassandraPersistentEntity.java @@ -34,9 +34,6 @@ import org.springframework.data.mapping.PropertyHandler; import org.springframework.data.mapping.model.BasicPersistentEntity; import org.springframework.data.mapping.model.MappingException; import org.springframework.data.util.TypeInformation; -import org.springframework.expression.Expression; -import org.springframework.expression.ParserContext; -import org.springframework.expression.spel.standard.SpelExpressionParser; import org.springframework.expression.spel.support.StandardEvaluationContext; import org.springframework.util.Assert; import org.springframework.util.StringUtils; @@ -54,9 +51,9 @@ public class BasicCassandraPersistentEntity extends BasicPersistentEntity typeInformation) { this(typeInformation, null); @@ -84,8 +81,6 @@ public class BasicCassandraPersistentEntity extends BasicPersistentEntity extends BasicPersistentEntity extends BasicPersistentEntity extends BasicPersistentEntity - implements CassandraPersistentProperty { + implements CassandraPersistentProperty, ApplicationContextAware { + + protected ApplicationContext context; + protected StandardEvaluationContext spelContext; /** * Creates a new {@link BasicCassandraPersistentProperty}. @@ -53,6 +67,22 @@ public class BasicCassandraPersistentProperty extends AnnotationBasedPersistentP CassandraPersistentEntity owner, CassandraSimpleTypeHolder simpleTypeHolder) { super(field, propertyDescriptor, owner, simpleTypeHolder); + + if (owner != null && owner.getApplicationContext() != null) { + setApplicationContext(owner.getApplicationContext()); + } + } + + @Override + public void setApplicationContext(ApplicationContext context) { + + Assert.notNull(context); + + this.context = context; + spelContext = new StandardEvaluationContext(); + spelContext.addPropertyAccessor(new BeanFactoryAccessor()); + spelContext.setBeanResolver(new BeanFactoryResolver(context)); + spelContext.setRootObject(context); } @Override @@ -83,9 +113,9 @@ public class BasicCassandraPersistentProperty extends AnnotationBasedPersistentP } @Override - public String getColumnName() { + public CqlIdentifier getColumnName() { - List columnNames = getColumnNames(); + List columnNames = getColumnNames(); if (columnNames.size() != 1) { throw new IllegalStateException("property does not have a single column mapping"); } @@ -226,9 +256,9 @@ public class BasicCassandraPersistentProperty extends AnnotationBasedPersistentP } @Override - public List getColumnNames() { + public List getColumnNames() { - final List columnNames = new ArrayList(); + List columnNames = new ArrayList(); if (isCompositePrimaryKey()) { addCompositePrimaryKeyColumnNames(getCompositePrimaryKeyEntity(), columnNames); @@ -238,24 +268,26 @@ public class BasicCassandraPersistentProperty extends AnnotationBasedPersistentP // else not a composite primary key property -- first check @Column annotation Column column = findAnnotation(Column.class); if (column != null && StringUtils.hasText(column.value())) { - columnNames.add(column.value()); + columnNames.add(cqlId(spelContext == null ? column.value() : SpelUtils.evaluate(column.value(), spelContext), + column.forceQuote())); return columnNames; } // else check @PrimaryKeyColumn annotation PrimaryKeyColumn pk = findAnnotation(PrimaryKeyColumn.class); if (pk != null && StringUtils.hasText(pk.name())) { - columnNames.add(pk.name()); + columnNames.add(cqlId(spelContext == null ? pk.name() : SpelUtils.evaluate(pk.name(), spelContext), + pk.forceQuote())); return columnNames; } // else default - columnNames.add(field.getName().toLowerCase()); // TODO: replace with naming strategy class + columnNames.add(cqlId(field.getName())); // TODO: replace with naming strategy class return columnNames; } protected void addCompositePrimaryKeyColumnNames(CassandraPersistentEntity compositePrimaryKeyEntity, - final List columnNames) { + final List columnNames) { compositePrimaryKeyEntity.doWithProperties(new PropertyHandler() { diff --git a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/mapping/CachingCassandraPersistentProperty.java b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/mapping/CachingCassandraPersistentProperty.java index ddbccda73..8fdbd0a38 100644 --- a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/mapping/CachingCassandraPersistentProperty.java +++ b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/mapping/CachingCassandraPersistentProperty.java @@ -20,6 +20,7 @@ import java.lang.reflect.Field; import java.util.List; import org.springframework.cassandra.core.Ordering; +import org.springframework.cassandra.core.cql.CqlIdentifier; import org.springframework.data.util.TypeInformation; import com.datastax.driver.core.DataType; @@ -38,8 +39,8 @@ public class CachingCassandraPersistentProperty extends BasicCassandraPersistent private Boolean isPartitionKeyColumn; private Boolean isClusterKeyColumn; private Boolean isPrimaryKeyColumn; - private String columnName; - private List columnNames; + private CqlIdentifier columnName; + private List columnNames; private Ordering ordering; private boolean orderingCached = false; private DataType dataType; @@ -128,7 +129,7 @@ public class CachingCassandraPersistentProperty extends BasicCassandraPersistent } @Override - public String getColumnName() { + public CqlIdentifier getColumnName() { if (columnName == null) { columnName = super.getColumnName(); @@ -155,7 +156,7 @@ public class CachingCassandraPersistentProperty extends BasicCassandraPersistent } @Override - public List getColumnNames() { + public List getColumnNames() { if (columnNames == null) { columnNames = super.getColumnNames(); } diff --git a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/mapping/CassandraPersistentEntity.java b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/mapping/CassandraPersistentEntity.java index 04c83b5d2..e402f4035 100644 --- a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/mapping/CassandraPersistentEntity.java +++ b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/mapping/CassandraPersistentEntity.java @@ -18,6 +18,7 @@ package org.springframework.data.cassandra.mapping; import java.util.List; import org.springframework.cassandra.core.cql.CqlIdentifier; +import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContextAware; import org.springframework.data.mapping.PersistentEntity; import org.springframework.data.mapping.model.MutablePersistentEntity; @@ -46,4 +47,6 @@ public interface CassandraPersistentEntity extends MutablePersistentEntity { +public interface CassandraPersistentProperty extends PersistentProperty, + ApplicationContextAware { /** * Whether the property is a composite primary key. @@ -59,13 +62,13 @@ public interface CassandraPersistentProperty extends PersistentProperty getColumnNames(); + List getColumnNames(); /** * The ordering (ascending or descending) for the column. Valid only for primary key columns; returns null for diff --git a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/util/CqlUtils.java b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/util/CqlUtils.java index 7fe7dd1a0..e1e047a14 100644 --- a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/util/CqlUtils.java +++ b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/util/CqlUtils.java @@ -52,7 +52,7 @@ public abstract class CqlUtils { @Override public void doWithPersistentProperty(CassandraPersistentProperty prop) { - String columnName = prop.getColumnName(); + String columnName = prop.getColumnName().toCql(); DataType columnDataType = prop.getDataType(); ColumnMetadata columnMetadata = table.getColumn(columnName.toLowerCase()); diff --git a/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/test/integration/mapping/BasicCassandraPersistentEntityIntegrationTests.java b/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/test/integration/mapping/BasicCassandraPersistentEntityIntegrationTests.java index 9ac54d563..e3cdb7a19 100644 --- a/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/test/integration/mapping/BasicCassandraPersistentEntityIntegrationTests.java +++ b/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/test/integration/mapping/BasicCassandraPersistentEntityIntegrationTests.java @@ -53,6 +53,7 @@ public class BasicCassandraPersistentEntityIntegrationTests { BasicCassandraPersistentEntity entity = new BasicCassandraPersistentEntity( ClassTypeInformation.from(Area.class)); + entity.setApplicationContext(context); assertThat(entity.getTableName().toCql(), is("a123")); } diff --git a/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/test/integration/mapping/BasicCassandraPersistentPropertyIntegrationTests.java b/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/test/integration/mapping/BasicCassandraPersistentPropertyIntegrationTests.java index 10afc3a09..18fb9df40 100644 --- a/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/test/integration/mapping/BasicCassandraPersistentPropertyIntegrationTests.java +++ b/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/test/integration/mapping/BasicCassandraPersistentPropertyIntegrationTests.java @@ -64,7 +64,7 @@ public class BasicCassandraPersistentPropertyIntegrationTests { public void usesAnnotatedColumnName() { Field field = ReflectionUtils.findField(Timeline.class, "text"); - assertThat(getPropertyFor(field).getColumnName(), is("message")); + assertThat(getPropertyFor(field).getColumnName().toCql(), is("message")); } @Test @@ -77,7 +77,7 @@ public class BasicCassandraPersistentPropertyIntegrationTests { @Test public void returnsPropertyNameForUnannotatedProperty() { Field field = ReflectionUtils.findField(Timeline.class, "time"); - assertThat(getPropertyFor(field).getColumnName(), is("time")); + assertThat(getPropertyFor(field).getColumnName().toCql(), is("time")); } private CassandraPersistentProperty getPropertyFor(Field field) { diff --git a/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/test/integration/mapping/CassandraCompositePrimaryKeyIntegrationTests.java b/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/test/integration/mapping/CassandraCompositePrimaryKeyIntegrationTests.java index 293509c25..ec13a0bf7 100644 --- a/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/test/integration/mapping/CassandraCompositePrimaryKeyIntegrationTests.java +++ b/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/test/integration/mapping/CassandraCompositePrimaryKeyIntegrationTests.java @@ -17,6 +17,7 @@ package org.springframework.data.cassandra.test.integration.mapping; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; +import static org.springframework.cassandra.core.cql.CqlIdentifier.cqlId; import java.io.Serializable; import java.lang.reflect.Field; @@ -28,6 +29,7 @@ import java.util.List; import org.junit.Before; import org.junit.Test; import org.springframework.cassandra.core.PrimaryKeyType; +import org.springframework.cassandra.core.cql.CqlIdentifier; import org.springframework.cassandra.core.keyspace.ColumnSpecification; import org.springframework.cassandra.core.keyspace.CreateTableSpecification; import org.springframework.data.cassandra.mapping.BasicCassandraPersistentProperty; @@ -59,6 +61,8 @@ public class CassandraCompositePrimaryKeyIntegrationTests { @PrimaryKeyClass static class Key implements Serializable { + private static final long serialVersionUID = 1L; + @PrimaryKeyColumn(ordinal = 0, type = PrimaryKeyType.PARTITIONED) String z; @@ -130,10 +134,10 @@ public class CassandraCompositePrimaryKeyIntegrationTests { assertTrue(property.isIdProperty()); assertTrue(property.isCompositePrimaryKey()); - List expectedColumnNames = Arrays.asList(new String[] { "z", "a" }); + List expectedColumnNames = Arrays.asList(new CqlIdentifier[] { cqlId("z"), cqlId("a") }); assertTrue(expectedColumnNames.equals(property.getColumnNames())); - List actualColumnNames = new ArrayList(); + List actualColumnNames = new ArrayList(); List properties = property.getCompositePrimaryKeyProperties(); for (CassandraPersistentProperty p : properties) { actualColumnNames.addAll(p.getColumnNames());