spring-data-dynamodb
spring-data-dynamodb copied to clipboard
Second instance of DynamoDBMapperConfig being created
In updating to 5.1.0, on startup we're now getting:
Unsatisfied dependency expressed through constructor parameter 1; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'dynamoDBMapper' defined in class path resource [{Propriety class details removed}]: Unsatisfied dependency expressed through method 'dynamoDBMapper' parameter 1; nested exception is org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type 'com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBMapperConfig' available: expected single matching bean but found 2: dynamoDBMapperConfig,dynamoDB-DynamoDBMapperConfig
We're creating the DynamoDBMapperConfig as per https://github.com/derjust/spring-data-dynamodb/wiki/Alter-table-name-during-runtime. Looks like something else is also now creating a DynamoDBMapperConfig.
Should these be created now in a different fashion?
@GynnRickerbyNZPost
I had the same problem and I found out that I was configuring another DynamoDBMapperConfig bean.
So I removed this extra bean and the error stopped, remaining only the dynamoDB-DynamoDBMapperConfig
.
Best regards,
Tiago Peixoto.
Yes, but I need to configure the DynamoDBMapperConfig to specify table name overrides.
The dynamoDB-DynamoDBMapperConfig
one is being created internally (and seems didn't use to be in previous versions), and there's no obvious new documentation on how to turn it off.
@GynnRickerbyNZPost
Have you tried to set dynamoDBMapperConfigRef
property of @EnableDynamoDBRepositories
to point to your custom config?
For exemple (in Kotlin):
@EnableDynamoDBRepositories(dynamoDBMapperConfigRef = "customDynamoDBMapperConfig")
class DynamoDbConfig() {
@Bean("customDynamoDBMapperConfig")
fun dynamoDBMapperConfig(): DynamoDBMapperConfig = DynamoDBMapperConfig.DEFAULT
}
Yes. And works fine in 5.0.4.
@Configuration
@EnableDynamoDBRepositories(dynamoDBMapperConfigRef = "dynamoDBMapperConfig")
public class DynamoDBConfig {
@Bean("dynamoDBMapperConfig")
public DynamoDBMapperConfig dynamoDBMapperConfig(final TableNameOverride tableNameOverrider) {
A quick looking around the code, it looks like DynamoDBMapperConfigFactory was added in 5.1.0, as a FactoryBean which Spring Boot is picking up.
Unfortunately since I've got it working with 5.0.4 I don't have the spare time (project manager is happy with older version working) to go back and work out the appropriate config to override the FactoryBean to use my own settings.
I ran into this same problem in Spring Boot, but didn't have to override the factory bean, I just removed the ConfigRef from the @EnabledDynamoDBRepositories annotation. If you have a DynamoDBMapperConfig bean the postProcessAfterInitialization method in the DynamoDBMapperConfigFactory will find it and use it.
Have you tried changing
@EnableDynamoDBRepositories(dynamoDBMapperConfigRef = "dynamoDBMapperConfig")
to just this
@EnableDynamoDBRepositories
If this is the correct intent, the documentation found here Alter table name during runtime may need to be updated.
I made a new fix related to this issue.
Any ETA on this? We'd been waiting for 5.1 to go to Spring Boot 2.1, but now we'll need to wait for this fix as well.
I figured out a couple ways to get around this until the next release.
First, when you are creating your @Bean
instances of the config and mapper, tag them with @org.springframework.context.annotation.Primary
Second, and not as good, in my opinion, use @javax.inject.Named
on other beans that get the above beans injected.
Hi, just to make it clear: I tried this library v5.1 following step by step the tutorial and I've the exception reported above:
Parameter 1 of constructor in org.socialsignin.spring.data.dynamodb.repository.util.Entity2DynamoDBTableSynchronizer required a single bean, but 2 were found:
- dynamoDBMapper: defined by method 'dynamoDBMapper' in class path resource [cloud/optix/server/config/DynamoDBConfig.class]
- dynamoDB-DynamoDBMapper: defined in null
I do not have a multiple dynamoDBMapperConfig, I'm just using the basic configuration. Should I move back to the previous version? I'm using Spring Boot 2.1.4
Thanks
@emckissick's suggestion worked for us. I'm not sure if there are any other possible pitfalls to using this approach, but simply removing the dynamoDBMapperConfigRef
from the @ EnableDynamoDBRepositories
annotation and including our own bean definition of the mapper config worked a treat.
Example:
@Configuration
@ConfigurationProperties("amazon.aws")
@Setter
@EnableDynamoDBRepositories(basePackages = "com.package.adapters.dynamodb")
public class PersistenceConfig {
@NotBlank
private String accessKey;
@NotBlank
private String secretKey;
@Bean
public AmazonDynamoDB amazonDynamoDB() {
BasicAWSCredentials credentials = new BasicAWSCredentials(accessKey, secretKey);
AWSStaticCredentialsProvider credentialsProvider = new AWSStaticCredentialsProvider(credentials);
return AmazonDynamoDBClientBuilder
.standard()
.withCredentials(credentialsProvider)
.build();
}
@Bean
public DynamoDBMapperConfig dynamoDBMapperConfig() {
return new DynamoDBMapperConfig.Builder()
.withTableNameOverride(withTableNamePrefix("local."))
.build();
}
}
Like others, I already had a @Bean DynamoDBMapperConfig
defined.
For me a combination of removing dynamoDBMapperConfigRef
from the @EnableDynamoDBRepositories annotation
and also marking my existing DynamoDBMapperConfig
bean definition as @Primary
seemed to do the trick.
The following does the trick for me. Primary annotation and the removal of dynamoDBMapperConfigRef
//Make sure there is no dynamoDBMapperConfigRef
@EnableDynamoDBRepositories(basePackageClasses = User.class)
@Bean
@Primary
public DynamoDBMapper dynamoDBMapper(AmazonDynamoDB amazonDynamoDB, DynamoDBMapperConfig config) {
return new DynamoDBMapper(amazonDynamoDB, config);
}
@Bean
@Primary
public DynamoDBMapperConfig dynamoDBMapperConfig() {
return DynamoDBMapperConfig.DEFAULT;
}