Skip to content

Commit a1fd61e

Browse files
committed
Add support for Value Expressions in @KeySpace.
Closes #613
1 parent e2c7be2 commit a1fd61e

File tree

6 files changed

+20
-12
lines changed

6 files changed

+20
-12
lines changed

src/main/antora/modules/ROOT/nav.adoc

+1
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
** xref:repositories/definition.adoc[]
88
** xref:repositories/create-instances.adoc[]
99
** xref:keyvalue/repository/map-repositories.adoc[]
10+
** xref:keyvalue/value-expressions.adoc[]
1011
** xref:repositories/query-keywords-reference.adoc[]
1112
** xref:repositories/query-return-types-reference.adoc[]
1213

src/main/antora/modules/ROOT/pages/keyvalue/template.adoc

+1-1
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ template.findAllOf(User.class); <2>
5656
<2> Returns only elements of type `User` stored in `persons` keyspace.
5757
====
5858

59-
TIP: `@KeySpace` supports https://docs.spring.io/spring/docs/{springVersion}/spring-framework-reference/core.html#expressions[SpEL] expressions allowing dynamic keyspace configuration.
59+
TIP: `@KeySpace` supports xref:keyvalue/value-expressions.adoc[Value Expressions] allowing dynamic keyspace configuration.
6060

6161
[[key-value.keyspaces-custom]]
6262
=== Custom KeySpace Annotation
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
include::{commons}@data-commons::page$value-expressions.adoc[]

src/main/java/org/springframework/data/keyvalue/annotation/KeySpace.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@
2727
/**
2828
* Marker interface for methods with {@link Persistent} annotations indicating the presence of a dedicated keyspace the
2929
* entity should reside in. If present the value will be picked up for resolving the keyspace. The {@link #value()}
30-
* attribute supports SpEL expressions to dynamically resolve the keyspace based on a per-operation basis.
30+
* attribute supports Value Expressions to dynamically resolve the keyspace based on a per-operation basis.
3131
*
3232
* <pre class="code">
3333
* &#64;Persistent

src/main/java/org/springframework/data/keyvalue/core/mapping/BasicKeyValuePersistentEntity.java

+9-7
Original file line numberDiff line numberDiff line change
@@ -15,13 +15,15 @@
1515
*/
1616
package org.springframework.data.keyvalue.core.mapping;
1717

18+
import org.springframework.data.expression.ValueExpression;
19+
import org.springframework.data.expression.ValueExpressionParser;
1820
import org.springframework.data.mapping.model.BasicPersistentEntity;
1921
import org.springframework.data.util.TypeInformation;
2022
import org.springframework.expression.Expression;
21-
import org.springframework.expression.ParserContext;
2223
import org.springframework.expression.common.LiteralExpression;
2324
import org.springframework.expression.spel.standard.SpelExpressionParser;
2425
import org.springframework.lang.Nullable;
26+
import org.springframework.util.ObjectUtils;
2527
import org.springframework.util.StringUtils;
2628

2729
/**
@@ -35,9 +37,9 @@
3537
public class BasicKeyValuePersistentEntity<T, P extends KeyValuePersistentProperty<P>>
3638
extends BasicPersistentEntity<T, P> implements KeyValuePersistentEntity<T, P> {
3739

38-
private static final SpelExpressionParser PARSER = new SpelExpressionParser();
40+
private static final ValueExpressionParser PARSER = ValueExpressionParser.create(SpelExpressionParser::new);
3941

40-
private final @Nullable Expression keyspaceExpression;
42+
private final @Nullable ValueExpression keyspaceExpression;
4143
private final @Nullable String keyspace;
4244

4345
/**
@@ -89,16 +91,16 @@ private BasicKeyValuePersistentEntity(TypeInformation<T> information, @Nullable
8991
* @return the parsed {@link Expression} or {@literal null}.
9092
*/
9193
@Nullable
92-
private static Expression detectExpression(String potentialExpression) {
94+
private static ValueExpression detectExpression(String potentialExpression) {
9395

94-
Expression expression = PARSER.parseExpression(potentialExpression, ParserContext.TEMPLATE_EXPRESSION);
95-
return expression instanceof LiteralExpression ? null : expression;
96+
ValueExpression expression = PARSER.parse(potentialExpression);
97+
return expression.isLiteral() ? null : expression;
9698
}
9799

98100
@Override
99101
public String getKeySpace() {
100102
return keyspaceExpression == null //
101103
? keyspace //
102-
: keyspaceExpression.getValue(getEvaluationContext(null), String.class);
104+
: ObjectUtils.nullSafeToString(keyspaceExpression.evaluate(getValueEvaluationContext(null)));
103105
}
104106
}

src/test/java/org/springframework/data/keyvalue/core/mapping/BasicKeyValuePersistentEntityUnitTests.java

+7-3
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
import org.springframework.data.keyvalue.core.mapping.context.KeyValueMappingContext;
2727
import org.springframework.data.spel.ExtensionAwareEvaluationContextProvider;
2828
import org.springframework.data.spel.spi.EvaluationContextExtension;
29+
import org.springframework.mock.env.MockEnvironment;
2930

3031
/**
3132
* Unit tests for {@link BasicKeyValuePersistentEntity}.
@@ -43,14 +44,17 @@ void shouldDeriveKeyspaceFromClassName() {
4344
.isEqualTo(KeyspaceEntity.class.getName());
4445
}
4546

46-
@Test // DATAKV-268
47+
@Test // DATAKV-268, GH-613
4748
void shouldEvaluateKeyspaceExpression() {
4849

50+
MockEnvironment environment = new MockEnvironment().withProperty("my.property", "foo");
51+
mappingContext.setEnvironment(environment);
52+
4953
KeyValuePersistentEntity<?, ?> persistentEntity = mappingContext.getPersistentEntity(ExpressionEntity.class);
5054
persistentEntity.setEvaluationContextProvider(
5155
new ExtensionAwareEvaluationContextProvider(Collections.singletonList(new SampleExtension())));
5256

53-
assertThat(persistentEntity.getKeySpace()).isEqualTo("some");
57+
assertThat(persistentEntity.getKeySpace()).isEqualTo("some_foo");
5458
}
5559

5660
@Test // DATAKV-268
@@ -81,7 +85,7 @@ void shouldFallBackToDefaultsIfKeySpaceResolverReturnsNull() {
8185
assertThat(persistentEntity.getKeySpace()).isEqualTo(NoKeyspaceEntity.class.getName());
8286
}
8387

84-
@KeySpace("#{myProperty}")
88+
@KeySpace("#{myProperty}_${my.property}")
8589
private static class ExpressionEntity {}
8690

8791
@KeySpace

0 commit comments

Comments
 (0)