Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

<groupId>org.springframework.data</groupId>
<artifactId>spring-data-keyvalue</artifactId>
<version>4.0.0-SNAPSHOT</version>
<version>4.0.0-GH-363-SNAPSHOT</version>

<name>Spring Data KeyValue</name>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,10 @@

import org.jspecify.annotations.Nullable;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.data.keyvalue.core.mapping.KeyValuePersistentEntity;
import org.springframework.data.keyvalue.core.mapping.KeyValuePersistentProperty;
import org.springframework.data.keyvalue.core.query.KeyValueQuery;
import org.springframework.data.mapping.context.MappingContext;
import org.springframework.data.util.CloseableIterator;

/**
Expand All @@ -32,6 +35,14 @@
*/
public interface KeyValueAdapter extends DisposableBean {

/**
* Expose the {@link MappingContext} to obtain mapping metadata.
*
* @return the used mapping context.
* @since 4.0
*/
MappingContext<? extends KeyValuePersistentEntity<?, ?>, ? extends KeyValuePersistentProperty<?>> getMappingContext();

/**
* Add object with given id to keyspace.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,38 +70,24 @@ public class KeyValueTemplate implements KeyValueOperations, ApplicationEventPub
* @param adapter must not be {@literal null}.
*/
public KeyValueTemplate(KeyValueAdapter adapter) {
this(adapter, new KeyValueMappingContext<>());
this(adapter, DefaultIdentifierGenerator.INSTANCE);
}

/**
* Create new {@link KeyValueTemplate} using the given {@link KeyValueAdapter} and {@link MappingContext}.
* Create new {@link KeyValueTemplate} using the given {@link KeyValueAdapter} and {@link IdentifierGenerator}.
*
* @param adapter must not be {@literal null}.
* @param mappingContext must not be {@literal null}.
*/
public KeyValueTemplate(KeyValueAdapter adapter,
MappingContext<? extends KeyValuePersistentEntity<?, ?>, ? extends KeyValuePersistentProperty<?>> mappingContext) {
this(adapter, mappingContext, DefaultIdentifierGenerator.INSTANCE);
}

/**
* Create new {@link KeyValueTemplate} using the given {@link KeyValueAdapter} and {@link MappingContext}.
*
* @param adapter must not be {@literal null}.
* @param mappingContext must not be {@literal null}.
* @param identifierGenerator must not be {@literal null}.
* @since 2.4
* @since 4.0
*/
public KeyValueTemplate(KeyValueAdapter adapter,
MappingContext<? extends KeyValuePersistentEntity<?, ?>, ? extends KeyValuePersistentProperty<?>> mappingContext,
IdentifierGenerator identifierGenerator) {

Assert.notNull(adapter, "Adapter must not be null");
Assert.notNull(mappingContext, "MappingContext must not be null");
Assert.notNull(identifierGenerator, "IdentifierGenerator must not be null");

this.adapter = adapter;
this.mappingContext = mappingContext;
this.mappingContext = adapter.getMappingContext();
this.identifierGenerator = identifierGenerator;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,14 +21,14 @@
import java.util.Optional;

import org.jspecify.annotations.Nullable;

import org.springframework.beans.factory.support.AbstractBeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.RootBeanDefinition;
import org.springframework.core.annotation.AnnotationAttributes;
import org.springframework.core.annotation.MergedAnnotation;
import org.springframework.core.type.AnnotationMetadata;
import org.springframework.data.keyvalue.core.mapping.context.KeyValueMappingContext;
import org.springframework.data.keyvalue.repository.KeyValueRepository;
import org.springframework.data.keyvalue.repository.query.KeyValuePartTreeQuery;
import org.springframework.data.keyvalue.repository.query.SpelQueryCreator;
Expand All @@ -47,7 +47,6 @@
*/
public abstract class KeyValueRepositoryConfigurationExtension extends RepositoryConfigurationExtensionSupport {

protected static final String MAPPING_CONTEXT_BEAN_NAME = "keyValueMappingContext";
protected static final String KEY_VALUE_TEMPLATE_BEAN_REF_ATTRIBUTE = "keyValueTemplateRef";

@Override
Expand Down Expand Up @@ -78,7 +77,6 @@ public void postProcess(BeanDefinitionBuilder builder, AnnotationRepositoryConfi
builder.addPropertyReference("keyValueOperations", attributes.getString(KEY_VALUE_TEMPLATE_BEAN_REF_ATTRIBUTE));
builder.addPropertyValue("queryCreator", getQueryCreatorType(config));
builder.addPropertyValue("queryType", getQueryType(config));
builder.addPropertyReference("mappingContext", getMappingContextBeanRef());
}

/**
Expand Down Expand Up @@ -128,15 +126,6 @@ public void registerBeansForRoot(BeanDefinitionRegistry registry, RepositoryConf

super.registerBeansForRoot(registry, configurationSource);

registerIfNotAlreadyRegistered(() -> {

RootBeanDefinition mappingContext = new RootBeanDefinition(KeyValueMappingContext.class);
mappingContext.setSource(configurationSource.getSource());

return mappingContext;

}, registry, getMappingContextBeanRef(), configurationSource);

Optional<String> keyValueTemplateName = configurationSource.getAttribute(KEY_VALUE_TEMPLATE_BEAN_REF_ATTRIBUTE);

// No custom template reference configured and no matching bean definition found
Expand Down Expand Up @@ -174,15 +163,4 @@ public void registerBeansForRoot(BeanDefinitionRegistry registry, RepositoryConf
*/
protected abstract String getDefaultKeyValueTemplateRef();

/**
* Returns the {@link org.springframework.data.mapping.context.MappingContext} bean name to potentially register a
* default mapping context bean if no bean is registered with the returned name. Defaults to
* {@link MAPPING_CONTEXT_BEAN_NAME}.
*
* @return the {@link org.springframework.data.mapping.context.MappingContext} bean name. Never {@literal null}.
* @since 2.0
*/
protected String getMappingContextBeanRef() {
return MAPPING_CONTEXT_BEAN_NAME;
}
}
15 changes: 15 additions & 0 deletions src/main/java/org/springframework/data/map/MapKeyValueAdapter.java
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,9 @@
import org.springframework.data.keyvalue.core.KeyValueAdapter;
import org.springframework.data.keyvalue.core.QueryEngine;
import org.springframework.data.keyvalue.core.SortAccessor;
import org.springframework.data.keyvalue.core.mapping.KeyValuePersistentEntity;
import org.springframework.data.keyvalue.core.mapping.KeyValuePersistentProperty;
import org.springframework.data.keyvalue.core.mapping.context.KeyValueMappingContext;
import org.springframework.data.util.CloseableIterator;
import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
Expand All @@ -38,12 +41,14 @@
* @author Christoph Strobl
* @author Derek Cochran
* @author Marcel Overdijk
* @author Mark Paluch
*/
public class MapKeyValueAdapter extends AbstractKeyValueAdapter {

@SuppressWarnings("rawtypes") //
private final Class<? extends Map> keySpaceMapType;
private final Map<String, Map<Object, Object>> store;
private KeyValueMappingContext<? extends KeyValuePersistentEntity<?, ?>, ? extends KeyValuePersistentProperty<?>> mappingContext = new KeyValueMappingContext<>();

/**
* Create new {@link MapKeyValueAdapter} using {@link ConcurrentHashMap} as backing store type.
Expand Down Expand Up @@ -143,6 +148,16 @@ private MapKeyValueAdapter(Map<String, Map<Object, Object>> store, Class<? exten
this.keySpaceMapType = keySpaceMapType;
}

@Override
public KeyValueMappingContext<? extends KeyValuePersistentEntity<?, ?>, ? extends KeyValuePersistentProperty<?>> getMappingContext() {
return mappingContext;
}

public void setMappingContext(
KeyValueMappingContext<? extends KeyValuePersistentEntity<?, ?>, ? extends KeyValuePersistentProperty<?>> mappingContext) {
this.mappingContext = mappingContext;
}

@Override
public @Nullable Object put(Object id, Object item, String keyspace) {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,13 +60,25 @@

/**
* Alias for the {@link #basePackages()} attribute. Allows for more concise annotation declarations e.g.:
* {@code @EnableJpaRepositories("org.my.pkg")} instead of {@code @EnableJpaRepositories(basePackages="org.my.pkg")}.
* {@code @EnableMapRepositories("org.my.pkg")} instead of {@code @EnableMapRepositories(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.
* Base packages to scan for annotated components.
* <p>
* {@link #value} is an alias for (and mutually exclusive with) this attribute.
* <p>
* Supports {@code ${…}} placeholders which are resolved against the {@link org.springframework.core.env.Environment
* Environment} as well as Ant-style package patterns &mdash; for example, {@code "org.example.**"}.
* <p>
* Multiple packages or patterns may be specified, either separately or within a single {@code String} &mdash; for
* example, {@code {"org.example.config", "org.example.service.**"}} or
* {@code "org.example.config, org.example.service.**"}.
* <p>
* Use {@link #basePackageClasses} for a type-safe alternative to String-based package names.
*
* @see org.springframework.context.ConfigurableApplicationContext#CONFIG_LOCATION_DELIMITERS
*/
String[] basePackages() default {};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@
import org.springframework.data.keyvalue.core.event.KeyValueEvent.BeforeGetEvent;
import org.springframework.data.keyvalue.core.event.KeyValueEvent.BeforeInsertEvent;
import org.springframework.data.keyvalue.core.event.KeyValueEvent.BeforeUpdateEvent;
import org.springframework.data.keyvalue.core.mapping.context.KeyValueMappingContext;
import org.springframework.data.keyvalue.core.query.KeyValueQuery;

/**
Expand All @@ -73,6 +74,7 @@ class KeyValueTemplateUnitTests {

@BeforeEach
void setUp() {
when(adapterMock.getMappingContext()).thenReturn(new KeyValueMappingContext());
this.template = new KeyValueTemplate(adapterMock);
this.template.setApplicationEventPublisher(publisherMock);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@
import org.springframework.data.keyvalue.core.QueryEngineFactory;
import org.springframework.data.keyvalue.core.SortAccessor;
import org.springframework.data.keyvalue.core.SpelQueryEngine;
import org.springframework.data.keyvalue.core.mapping.context.KeyValueMappingContext;
import org.springframework.data.keyvalue.core.query.KeyValueQuery;
import org.springframework.data.keyvalue.repository.KeyValueRepository;
import org.springframework.data.keyvalue.repository.query.PredicateQueryCreator;
Expand Down Expand Up @@ -220,7 +221,7 @@ public KeyValueOperations mapKeyValueTemplate() {
public KeyValueAdapter keyValueAdapter() {

KeyValueAdapter mock = mock(KeyValueAdapter.class);

when(mock.getMappingContext()).thenReturn(new KeyValueMappingContext());
when(mock.get(any(), anyString(), any())).thenThrow(new IllegalStateException("Mock"));

return mock;
Expand Down