Sample of custom repository factory.

This commit is contained in:
mikereiche
2023-10-24 17:30:50 -07:00
parent 8404616bcc
commit deafc76597
8 changed files with 146 additions and 6 deletions

View File

@@ -5,7 +5,7 @@
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-couchbase</artifactId>
<version>5.2.0-SNAPSHOT</version>
<version>5.1.4</version>
<name>Spring Data Couchbase</name>
<description>Spring Data integration for Couchbase</description>

View File

@@ -452,7 +452,7 @@ public abstract class AbstractCouchbaseConfiguration {
return customConversions;
}
Map<Class<? extends Annotation>, Class<?>> annotationToConverterMap() {
public static Map<Class<? extends Annotation>, Class<?>> annotationToConverterMap() {
Map<Class<? extends Annotation>, Class<?>> map = new HashMap();
map.put(Encrypted.class, CryptoConverter.class);
map.put(JsonValue.class, JsonValueConverter.class);

View File

@@ -31,6 +31,7 @@ import java.util.List;
import java.util.Set;
import java.util.function.Consumer;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.core.convert.converter.Converter;
import org.springframework.core.convert.converter.ConverterFactory;
import org.springframework.core.convert.converter.GenericConverter;
@@ -39,6 +40,7 @@ import org.springframework.data.convert.PropertyValueConverter;
import org.springframework.data.convert.PropertyValueConverterFactory;
import org.springframework.data.convert.PropertyValueConverterRegistrar;
import org.springframework.data.convert.SimplePropertyValueConversions;
import org.springframework.data.couchbase.config.AbstractCouchbaseConfiguration;
import org.springframework.data.couchbase.core.mapping.CouchbasePersistentProperty;
import org.springframework.data.couchbase.core.mapping.CouchbaseSimpleTypes;
import org.springframework.data.mapping.PersistentProperty;
@@ -145,6 +147,41 @@ public class CouchbaseCustomConversions extends org.springframework.data.convert
CouchbaseConverterConfigurationAdapter converterConfigurationAdapter = new CouchbaseConverterConfigurationAdapter();
converterConfigurationAdapter.registerConverters(converters);
// The following
ObjectMapper om = new AbstractCouchbaseConfiguration() {
@Override
public String getConnectionString() {
return null;
}
@Override
public String getUserName() {
return null;
}
@Override
public String getPassword() {
return null;
}
@Override
public String getBucketName() {
return null;
}
}.getObjectMapper();
List<Object> newConverters = new ArrayList();
newConverters.add(new OtherConverters.EnumToObject(om));
newConverters.add(new IntegerToEnumConverterFactory(om));
newConverters.add(new StringToEnumConverterFactory(om));
newConverters.add(new BooleanToEnumConverterFactory(om));
SimplePropertyValueConversions valueConversions = new SimplePropertyValueConversions();
valueConversions.setConverterFactory(
new CouchbasePropertyValueConverterFactory(null, AbstractCouchbaseConfiguration.annotationToConverterMap(), om));
valueConversions.setValueConverterRegistry(new PropertyValueConverterRegistrar().buildRegistry());
valueConversions.afterPropertiesSet(); // wraps the CouchbasePropertyValueConverterFactory with CachingPVCFactory
converterConfigurationAdapter.setPropertyValueConversions(valueConversions);
converterConfigurationAdapter.registerConverters(newConverters);
converterConfigurationAdapter.registerConverters(newConverters);
return converterConfigurationAdapter;
}

View File

@@ -52,6 +52,7 @@ public class ReactiveCouchbaseRepositoryFactory extends ReactiveRepositoryFactor
* Holds the reference to the template.
*/
private final ReactiveRepositoryOperationsMapping couchbaseOperationsMapping;
private ReactiveRepositoryOperationsMapping couchbaseOperationsMappingFallback;
/**
* Holds the mapping context.
@@ -60,6 +61,16 @@ public class ReactiveCouchbaseRepositoryFactory extends ReactiveRepositoryFactor
private final CrudMethodMetadataPostProcessor crudMethodMetadataPostProcessor;
/**
* Create a new factory.
*
* @param couchbaseOperationsMapping the template for the underlying actions.
*/
public ReactiveCouchbaseRepositoryFactory(final ReactiveRepositoryOperationsMapping couchbaseOperationsMapping, final ReactiveRepositoryOperationsMapping couchbaseOperationsMappingFallback){
this(couchbaseOperationsMapping);
this.couchbaseOperationsMappingFallback = couchbaseOperationsMappingFallback;
}
/**
* Create a new factory.
*
@@ -109,9 +120,11 @@ public class ReactiveCouchbaseRepositoryFactory extends ReactiveRepositoryFactor
protected final Object getTargetRepository(final RepositoryInformation metadata) {
ReactiveCouchbaseOperations couchbaseOperations = couchbaseOperationsMapping
.resolve(metadata.getRepositoryInterface(), metadata.getDomainType());
ReactiveCouchbaseOperations couchbaseOperationsFallback = couchbaseOperationsMappingFallback
.resolve(metadata.getRepositoryInterface(), metadata.getDomainType());
CouchbaseEntityInformation<?, Serializable> entityInformation = getEntityInformation(metadata.getDomainType());
SimpleReactiveCouchbaseRepository repository = getTargetRepositoryViaReflection(metadata, entityInformation,
couchbaseOperations, metadata.getRepositoryInterface());
couchbaseOperations, couchbaseOperationsFallback, metadata.getRepositoryInterface());
repository.setRepositoryMethodMetadata(crudMethodMetadataPostProcessor.getCrudMethodMetadata());
return repository;
}

View File

@@ -53,7 +53,7 @@ public class SimpleReactiveCouchbaseRepository<T, ID> extends CouchbaseRepositor
* Holds the reference to the {@link CouchbaseOperations}.
*/
private final ReactiveCouchbaseOperations operations;
private final ReactiveCouchbaseOperations operationsFallback;
/**
* Create a new Repository.
*
@@ -61,9 +61,10 @@ public class SimpleReactiveCouchbaseRepository<T, ID> extends CouchbaseRepositor
* @param operations the reference to the reactive template used.
*/
public SimpleReactiveCouchbaseRepository(CouchbaseEntityInformation<T, String> entityInformation,
ReactiveCouchbaseOperations operations, Class<?> repositoryInterface) {
ReactiveCouchbaseOperations operations, ReactiveCouchbaseOperations operationsFallback,Class<?> repositoryInterface) {
super(entityInformation, repositoryInterface);
this.operations = operations;
this.operationsFallback = operationsFallback;
}
@Override

View File

@@ -26,6 +26,7 @@ import org.springframework.data.couchbase.CouchbaseClientFactory;
import org.springframework.data.couchbase.SimpleCouchbaseClientFactory;
import org.springframework.data.couchbase.cache.CouchbaseCacheManager;
import org.springframework.data.couchbase.config.AbstractCouchbaseConfiguration;
import org.springframework.data.couchbase.config.BeanNames;
import org.springframework.data.couchbase.core.CouchbaseTemplate;
import org.springframework.data.couchbase.core.ReactiveCouchbaseTemplate;
import org.springframework.data.couchbase.core.convert.CouchbaseCustomConversions;
@@ -55,7 +56,8 @@ import com.couchbase.client.java.json.JacksonTransformers;
*/
@Configuration
@EnableCouchbaseRepositories
@EnableReactiveCouchbaseRepositories
@EnableReactiveCouchbaseRepositories(repositoryFactoryBeanClass=MyReactiveCouchbaseRepositoryFactoryBean.class)
//@EnableReactiveCouchbaseRepositories
@EnableCouchbaseAuditing(dateTimeProviderRef = "dateTimeProviderRef")
@EnableReactiveCouchbaseAuditing(dateTimeProviderRef = "dateTimeProviderRef")
@EnableCaching
@@ -148,6 +150,13 @@ public class Config extends AbstractCouchbaseConfiguration {
}
}
@Bean(name = BeanNames.REACTIVE_COUCHBASE_TEMPLATE)
public ReactiveCouchbaseTemplate reactiveCouchbaseTemplate(CouchbaseClientFactory couchbaseClientFactory, CouchbaseClientFactory couchbaseClientFactory2,
MappingCouchbaseConverter mappingCouchbaseConverter, TranslationService couchbaseTranslationService) {
return new ReactiveCouchbaseTemplate(couchbaseClientFactory, mappingCouchbaseConverter, couchbaseTranslationService,
getDefaultConsistency());
}
@Override
public void configureRepositoryOperationsMapping(RepositoryOperationsMapping baseMapping) {
try {

View File

@@ -0,0 +1,79 @@
package org.springframework.data.couchbase.domain;
import org.springframework.data.couchbase.core.ReactiveCouchbaseOperations;
import org.springframework.data.couchbase.repository.config.ReactiveRepositoryOperationsMapping;
import org.springframework.data.couchbase.repository.support.ReactiveCouchbaseRepositoryFactory;
import org.springframework.data.couchbase.repository.support.ReactiveCouchbaseRepositoryFactoryBean;
import org.springframework.data.repository.Repository;
import org.springframework.data.repository.core.support.RepositoryFactorySupport;
import org.springframework.util.Assert;
import java.io.Serializable;
public class MyReactiveCouchbaseRepositoryFactoryBean<T extends Repository<S, ID>, S, ID extends Serializable> extends ReactiveCouchbaseRepositoryFactoryBean<T, S, ID> {
/**
* Contains the reference to the template.
*/
private ReactiveRepositoryOperationsMapping couchbaseOperationsMapping;
/**
* Contains the reference to the template.
*/
private ReactiveRepositoryOperationsMapping couchbaseOperationsMappingFallback;
/**
* Creates a new {@link CouchbaseRepositoryFactoryBean} for the given repository interface.
*
* @param repositoryInterface must not be {@literal null}.
*/
public MyReactiveCouchbaseRepositoryFactoryBean(Class repositoryInterface) {
super(repositoryInterface);
}
/**
* Returns a factory instance.
*
* @return the factory instance.
*/
@Override
protected RepositoryFactorySupport createRepositoryFactory() {
return getFactoryInstance(couchbaseOperationsMapping);
}
/**
* Get the factory instance for the operations.
*
* @param couchbaseOperationsMapping the reference to the template.
* @return the factory instance.
*/
protected ReactiveCouchbaseRepositoryFactory getFactoryInstance(
final ReactiveRepositoryOperationsMapping couchbaseOperationsMapping) {
return new ReactiveCouchbaseRepositoryFactory(couchbaseOperationsMapping, couchbaseOperationsMappingFallback);
}
/**
* Set the template reference.
*
* @param reactiveCouchbaseOperations the reference to the operations template.
*/
public void setCouchbaseOperations(final ReactiveCouchbaseOperations reactiveCouchbaseOperations) {
setReactiveCouchbaseOperationsMapping(new ReactiveRepositoryOperationsMapping(reactiveCouchbaseOperations));
}
public void setReactiveCouchbaseOperationsMapping(
final ReactiveRepositoryOperationsMapping couchbaseOperationsMapping) {
super.setReactiveCouchbaseOperationsMapping(couchbaseOperationsMapping);
this.couchbaseOperationsMapping = couchbaseOperationsMapping;
setMappingContext(couchbaseOperationsMapping.getMappingContext());
this.couchbaseOperationsMappingFallback = couchbaseOperationsMapping;
setMappingContext(couchbaseOperationsMapping.getMappingContext());
}
/**
* Make sure that the dependencies are set and not null.
*/
//@Override
//public void afterPropertiesSet() {
// super.afterPropertiesSet();
// Assert.notNull(couchbaseOperationsMapping, "operationsMapping must not be null!");
//}
}

View File

@@ -168,6 +168,7 @@ public class CouchbaseRepositoryQueryIntegrationTests extends ClusterAwareIntegr
try {
vie = new Airport("airports::vie", "vie", "low4");
vie.setSize(2);
reactiveAirportRepository.count().block();
airportRepository.save(vie);
List<Airport> all = new ArrayList<>();
airportRepository.findAll().forEach(all::add);