spring-data-dynamodb icon indicating copy to clipboard operation
spring-data-dynamodb copied to clipboard

Error running Spring Boot Tests when a webEnvironment has been enabled

Open stewartmatheson opened this issue 6 years ago • 35 comments

Expected Behavior

The application context to load when using spring boot test with the web environment

@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)

Actual Behavior

The context fails to load. The following error is reported.

  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::        (v2.1.2.RELEASE)

2019-01-30 17:26:14.747  INFO 8611 --- [    Test worker] com.example.demo.DemoApplicationTests    : Starting DemoApplicationTests on StewartsMBP2191 with PID 8611 (started by stewartmatheson in /Users/stewartmatheson/Downloads/demo 2)
2019-01-30 17:26:14.748  INFO 8611 --- [    Test worker] com.example.demo.DemoApplicationTests    : No active profile set, falling back to default profiles: default
2019-01-30 17:26:14.975  INFO 8611 --- [    Test worker] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data repositories in DEFAULT mode.
2019-01-30 17:26:15.021  INFO 8611 --- [    Test worker] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 8ms. Found 0 repository interfaces.
2019-01-30 17:26:15.081  WARN 8611 --- [    Test worker] s.c.a.AnnotationConfigApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'dynamoDB-DynamoDBMapper': Instantiation of bean failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.socialsignin.spring.data.dynamodb.repository.config.DynamoDBMapperFactory]: No default constructor found; nested exception is java.lang.NoSuchMethodException: org.socialsignin.spring.data.dynamodb.repository.config.DynamoDBMapperFactory.<init>()
2019-01-30 17:26:15.092  INFO 8611 --- [    Test worker] ConditionEvaluationReportLoggingListener : 

Error starting ApplicationContext. To display the conditions report re-run your application with 'debug' enabled.
2019-01-30 17:26:15.100 ERROR 8611 --- [    Test worker] o.s.boot.SpringApplication               : Application run failed

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'dynamoDB-DynamoDBMapper': Instantiation of bean failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.socialsignin.spring.data.dynamodb.repository.config.DynamoDBMapperFactory]: No default constructor found; nested exception is java.lang.NoSuchMethodException: org.socialsignin.spring.data.dynamodb.repository.config.DynamoDBMapperFactory.<init>()
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateBean(AbstractAutowireCapableBeanFactory.java:1270) ~[spring-beans-5.1.4.RELEASE.jar:5.1.4.RELEASE]
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1164) ~[spring-beans-5.1.4.RELEASE.jar:5.1.4.RELEASE]
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.getSingletonFactoryBeanForTypeCheck(AbstractAutowireCapableBeanFactory.java:974) ~[spring-beans-5.1.4.RELEASE.jar:5.1.4.RELEASE]
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.getTypeForFactoryBean(AbstractAutowireCapableBeanFactory.java:848) ~[spring-beans-5.1.4.RELEASE.jar:5.1.4.RELEASE]
	at org.springframework.beans.factory.support.AbstractBeanFactory.isTypeMatch(AbstractBeanFactory.java:574) ~[spring-beans-5.1.4.RELEASE.jar:5.1.4.RELEASE]
	at org.springframework.beans.factory.support.DefaultListableBeanFactory.doGetBeanNamesForType(DefaultListableBeanFactory.java:514) ~[spring-beans-5.1.4.RELEASE.jar:5.1.4.RELEASE]
	at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBeanNamesForType(DefaultListableBeanFactory.java:477) ~[spring-beans-5.1.4.RELEASE.jar:5.1.4.RELEASE]
	at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBeanNamesForType(DefaultListableBeanFactory.java:471) ~[spring-beans-5.1.4.RELEASE.jar:5.1.4.RELEASE]
	at org.springframework.beans.factory.BeanFactoryUtils.beanNamesForTypeIncludingAncestors(BeanFactoryUtils.java:190) ~[spring-beans-5.1.4.RELEASE.jar:5.1.4.RELEASE]
	at org.springframework.boot.test.web.client.TestRestTemplateContextCustomizer$TestRestTemplateRegistrar.postProcessBeanDefinitionRegistry(TestRestTemplateContextCustomizer.java:113) ~[spring-boot-test-2.1.2.RELEASE.jar:2.1.2.RELEASE]
	at org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanDefinitionRegistryPostProcessors(PostProcessorRegistrationDelegate.java:275) ~[spring-context-5.1.4.RELEASE.jar:5.1.4.RELEASE]
	at org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(PostProcessorRegistrationDelegate.java:108) ~[spring-context-5.1.4.RELEASE.jar:5.1.4.RELEASE]
	at org.springframework.context.support.AbstractApplicationContext.invokeBeanFactoryPostProcessors(AbstractApplicationContext.java:691) ~[spring-context-5.1.4.RELEASE.jar:5.1.4.RELEASE]
	at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:528) ~[spring-context-5.1.4.RELEASE.jar:5.1.4.RELEASE]
	at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:775) ~[spring-boot-2.1.2.RELEASE.jar:2.1.2.RELEASE]
	at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:397) ~[spring-boot-2.1.2.RELEASE.jar:2.1.2.RELEASE]
	at org.springframework.boot.SpringApplication.run(SpringApplication.java:316) ~[spring-boot-2.1.2.RELEASE.jar:2.1.2.RELEASE]
	at org.springframework.boot.test.context.SpringBootContextLoader.loadContext(SpringBootContextLoader.java:127) [spring-boot-test-2.1.2.RELEASE.jar:2.1.2.RELEASE]
	at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContextInternal(DefaultCacheAwareContextLoaderDelegate.java:99) [spring-test-5.1.4.RELEASE.jar:5.1.4.RELEASE]
	at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:117) [spring-test-5.1.4.RELEASE.jar:5.1.4.RELEASE]
	at org.springframework.test.context.support.DefaultTestContext.getApplicationContext(DefaultTestContext.java:108) [spring-test-5.1.4.RELEASE.jar:5.1.4.RELEASE]
	at org.springframework.test.context.support.DependencyInjectionTestExecutionListener.injectDependencies(DependencyInjectionTestExecutionListener.java:118) [spring-test-5.1.4.RELEASE.jar:5.1.4.RELEASE]
	at org.springframework.test.context.support.DependencyInjectionTestExecutionListener.prepareTestInstance(DependencyInjectionTestExecutionListener.java:83) [spring-test-5.1.4.RELEASE.jar:5.1.4.RELEASE]
	at org.springframework.boot.test.autoconfigure.SpringBootDependencyInjectionTestExecutionListener.prepareTestInstance(SpringBootDependencyInjectionTestExecutionListener.java:44) [spring-boot-test-autoconfigure-2.1.2.RELEASE.jar:2.1.2.RELEASE]
	at org.springframework.test.context.TestContextManager.prepareTestInstance(TestContextManager.java:246) [spring-test-5.1.4.RELEASE.jar:5.1.4.RELEASE]
	at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.createTest(SpringJUnit4ClassRunner.java:227) [spring-test-5.1.4.RELEASE.jar:5.1.4.RELEASE]
	at org.springframework.test.context.junit4.SpringJUnit4ClassRunner$1.runReflectiveCall(SpringJUnit4ClassRunner.java:289) [spring-test-5.1.4.RELEASE.jar:5.1.4.RELEASE]
	at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12) [junit-4.12.jar:4.12]
	at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.methodBlock(SpringJUnit4ClassRunner.java:291) [spring-test-5.1.4.RELEASE.jar:5.1.4.RELEASE]
	at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:246) [spring-test-5.1.4.RELEASE.jar:5.1.4.RELEASE]
	at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:97) [spring-test-5.1.4.RELEASE.jar:5.1.4.RELEASE]
	at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290) [junit-4.12.jar:4.12]
	at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71) [junit-4.12.jar:4.12]
	at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288) [junit-4.12.jar:4.12]
	at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58) [junit-4.12.jar:4.12]
	at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268) [junit-4.12.jar:4.12]
	at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61) [spring-test-5.1.4.RELEASE.jar:5.1.4.RELEASE]
	at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70) [spring-test-5.1.4.RELEASE.jar:5.1.4.RELEASE]
	at org.junit.runners.ParentRunner.run(ParentRunner.java:363) [junit-4.12.jar:4.12]
	at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:190) [spring-test-5.1.4.RELEASE.jar:5.1.4.RELEASE]
	at org.gradle.api.internal.tasks.testing.junit.JUnitTestClassExecutor.runTestClass(JUnitTestClassExecutor.java:106) [gradle-testing-jvm-4.10.2.jar:4.10.2]
	at org.gradle.api.internal.tasks.testing.junit.JUnitTestClassExecutor.execute(JUnitTestClassExecutor.java:58) [gradle-testing-jvm-4.10.2.jar:4.10.2]
	at org.gradle.api.internal.tasks.testing.junit.JUnitTestClassExecutor.execute(JUnitTestClassExecutor.java:38) [gradle-testing-jvm-4.10.2.jar:4.10.2]
	at org.gradle.api.internal.tasks.testing.junit.AbstractJUnitTestClassProcessor.processTestClass(AbstractJUnitTestClassProcessor.java:66) [gradle-testing-jvm-4.10.2.jar:4.10.2]
	at org.gradle.api.internal.tasks.testing.SuiteTestClassProcessor.processTestClass(SuiteTestClassProcessor.java:51) [gradle-testing-base-4.10.2.jar:4.10.2]
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_144]
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_144]
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_144]
	at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_144]
	at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:35) [gradle-messaging-4.10.2.jar:4.10.2]
	at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:24) [gradle-messaging-4.10.2.jar:4.10.2]
	at org.gradle.internal.dispatch.ContextClassLoaderDispatch.dispatch(ContextClassLoaderDispatch.java:32) [gradle-messaging-4.10.2.jar:4.10.2]
	at org.gradle.internal.dispatch.ProxyDispatchAdapter$DispatchingInvocationHandler.invoke(ProxyDispatchAdapter.java:93) [gradle-messaging-4.10.2.jar:4.10.2]
	at com.sun.proxy.$Proxy2.processTestClass(Unknown Source) [na:na]
	at org.gradle.api.internal.tasks.testing.worker.TestWorker.processTestClass(TestWorker.java:117) [gradle-testing-base-4.10.2.jar:4.10.2]
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_144]
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_144]
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_144]
	at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_144]
	at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:35) [gradle-messaging-4.10.2.jar:4.10.2]
	at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:24) [gradle-messaging-4.10.2.jar:4.10.2]
	at org.gradle.internal.remote.internal.hub.MessageHubBackedObjectConnection$DispatchWrapper.dispatch(MessageHubBackedObjectConnection.java:155) [gradle-messaging-4.10.2.jar:4.10.2]
	at org.gradle.internal.remote.internal.hub.MessageHubBackedObjectConnection$DispatchWrapper.dispatch(MessageHubBackedObjectConnection.java:137) [gradle-messaging-4.10.2.jar:4.10.2]
	at org.gradle.internal.remote.internal.hub.MessageHub$Handler.run(MessageHub.java:404) [gradle-messaging-4.10.2.jar:4.10.2]
	at org.gradle.internal.concurrent.ExecutorPolicy$CatchAndRecordFailures.onExecute(ExecutorPolicy.java:63) [gradle-base-services-4.10.2.jar:4.10.2]
	at org.gradle.internal.concurrent.ManagedExecutorImpl$1.run(ManagedExecutorImpl.java:46) [gradle-base-services-4.10.2.jar:4.10.2]
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) [na:1.8.0_144]
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) [na:1.8.0_144]
	at org.gradle.internal.concurrent.ThreadFactoryImpl$ManagedThreadRunnable.run(ThreadFactoryImpl.java:55) [gradle-base-services-4.10.2.jar:4.10.2]
	at java.lang.Thread.run(Thread.java:748) [na:1.8.0_144]
Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.socialsignin.spring.data.dynamodb.repository.config.DynamoDBMapperFactory]: No default constructor found; nested exception is java.lang.NoSuchMethodException: org.socialsignin.spring.data.dynamodb.repository.config.DynamoDBMapperFactory.<init>()
	at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:83) ~[spring-beans-5.1.4.RELEASE.jar:5.1.4.RELEASE]
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateBean(AbstractAutowireCapableBeanFactory.java:1262) ~[spring-beans-5.1.4.RELEASE.jar:5.1.4.RELEASE]
	... 69 common frames omitted
Caused by: java.lang.NoSuchMethodException: org.socialsignin.spring.data.dynamodb.repository.config.DynamoDBMapperFactory.<init>()
	at java.lang.Class.getConstructor0(Class.java:3082) ~[na:1.8.0_144]
	at java.lang.Class.getDeclaredConstructor(Class.java:2178) ~[na:1.8.0_144]
	at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:78) ~[spring-beans-5.1.4.RELEASE.jar:5.1.4.RELEASE]
	... 70 common frames omitted

Steps to Reproduce the Problem

  1. Start a project using the spring initializr
  2. Add the deps for the last version of spring data dynamodb
  3. Enable the webEnvironment within SpringBootTest
  4. Execute the test.

Specifications

  • Spring Data DynamoDB Version: 5.1.0
  • Spring Data Version:
  • AWS SDK Version: 1.11.443
  • Java Version: 8
  • Platform Details: Mac OSX

All those information are logged by org.socialsignin.spring.data.dynamodb.repository.support.DynamoDBRepositoryFactory on INFO level on startup. Or use java -version and mvn dependency:tree | grep -E 'spring|aws' to provide those version numbers.

stewartmatheson avatar Jan 30 '19 06:01 stewartmatheson

In case it helps, I'm experiencing the exact same thing with the same specifications, except I'm using Ubuntu 16.04.

gdtroszak avatar Jan 30 '19 17:01 gdtroszak

Same for us.

  • Java 11
  • AWS 1.11.472
  • Spring-boot 2.1.1.RELEASE

jakobgalbavy avatar Jan 31 '19 17:01 jakobgalbavy

Why is DynamoDBMapperFactory necessary? Looking at the source, it has a single @Autowired constructor that accepts AmazonDynamoDB and DynamoDBMapperConfig.

DynamoDBMapper is (putatively) thread-safe and should be a singleton; passing instances of AmazonDynamoDB and DynamoDBMapperConfig to this class, it would always return identical instances of the mapper.

EDIT: OK so it seems by default, FactoryBean instances are marked as returning singleton instances of their created class. Still, it seems that BeanFactory classes in conjunction with @Autowired constructors is an iffy proposition.

ryonday avatar Jan 31 '19 17:01 ryonday

Same here.

  • Spring Data DynamoDB Version: 5.1.0
  • Java 11.0.2
  • AWS 1.11.415
  • Spring-boot 2.1.2.RELEASE
  • Platform Details: Win 10 Pro

EDIT: My tests have the following configuration: @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.NONE)

tiagocpeixoto avatar Feb 03 '19 16:02 tiagocpeixoto

@ryonday

Maybe the code should be something like this ...

public class DynamoDBMapperFactory implements FactoryBean<DynamoDBMapper> {
	@Autowired
	private AmazonDynamoDB amazonDynamoDB;
	
	@Autowired
	private DynamoDBMapperConfig dynamoDBMapperConfig;
	
	public DynamoDBMapperFactory() {}

	@Override
	public DynamoDBMapper getObject() throws Exception {
		return new DynamoDBMapper(amazonDynamoDB, dynamoDBMapperConfig);
	}

	@Override
	public Class<?> getObjectType() {
		return DynamoDBMapper.class;
	}
}

instead of ...

public class DynamoDBMapperFactory implements FactoryBean<DynamoDBMapper> {
	private final AmazonDynamoDB amazonDynamoDB;
	private final DynamoDBMapperConfig dynamoDBMapperConfig;

	@Autowired
	public DynamoDBMapperFactory(AmazonDynamoDB amazonDynamoDB, DynamoDBMapperConfig dynamoDBMapperConfig) {
		this.amazonDynamoDB = amazonDynamoDB;
		this.dynamoDBMapperConfig = dynamoDBMapperConfig;
	}

	@Override
	public DynamoDBMapper getObject() throws Exception {
		return new DynamoDBMapper(amazonDynamoDB, dynamoDBMapperConfig);
	}

	@Override
	public Class<?> getObjectType() {
		return DynamoDBMapper.class;
	}
 } 

???

tiagocpeixoto avatar Feb 07 '19 13:02 tiagocpeixoto

Hi @stewartmatheson,

I'm also facing the same issue. Is there a work around for this to get the test classes run ? Thanks in advance!!!

ghost avatar Feb 07 '19 18:02 ghost

@ryonday interestingly I have both of these types wired in my configuration class. I would expect spring to be able to provide them in to the mapper factory unless I have missed something.

@ghost Change

@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)

to

@SpringBootTest

stewartmatheson avatar Feb 08 '19 02:02 stewartmatheson

Hi @stewartmatheson, I tried using @SpringBootTest instead of @SpringBootTest(webEnvironment=SpringBootTest.WebEnvironment.MOCK, classes={Main.class}), but still it results in the same error -> ava.lang.IllegalStateException: Failed to load ApplicationContext at xyz.class Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'dynamoDB-DynamoDBMapper': Instantiation of bean failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.socialsignin.spring.data.dynamodb.repository.config.DynamoDBMapperFactory]: No default constructor found; nested exception is java.lang.NoSuchMethodException: org.socialsignin.spring.data.dynamodb.repository.config.DynamoDBMapperFactory.()

Please help

GitUser753 avatar Feb 09 '19 00:02 GitUser753

Hi @derjust @ryonday @stewartmatheson ,

Any idea on when to expect this issue #230 to be resolved ?

GitUser753 avatar Feb 11 '19 23:02 GitUser753

I made a fix, but I can't create a branch to the pull request. I need help!

tiagocpeixoto avatar Feb 13 '19 16:02 tiagocpeixoto

You should be able to branch this to your own Github, push the Changes and then PR from there to this Repo here. See other PRs as a blueprint on how to do this.

jakobgalbavy avatar Feb 13 '19 16:02 jakobgalbavy

@tiagocpeixoto can you push your branch somewhere or send me a patch? I will test for you with my setup and create the PR for you if thats easier.

stewartmatheson avatar Feb 13 '19 23:02 stewartmatheson

@stewartmatheson @jakobgalbavy

Thank you! I created a PR. Hope it helps!

Feel free to give me feedback.

tiagocpeixoto avatar Feb 14 '19 15:02 tiagocpeixoto

Hi @tiagocpeixoto , looks like some checks have failed on the PR.

GitUser753 avatar Feb 19 '19 18:02 GitUser753

Do you know IF the PR can be accepted and WHEN it will be?

TY.

tiagocpeixoto avatar Feb 27 '19 12:02 tiagocpeixoto

@derjust Could someone review it's merged request 🙏

piclemx avatar Feb 28 '19 14:02 piclemx

@tiagocpeixoto looks like the fix didn't completely resolve the issue. I am still seeing this error with your fix. ( I have published a jar from the master branch, into our nexus repo and used it as the dependency for my project)

	at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:769) ~[spring-beans-5.1.5.RELEASE.jar:5.1.5.RELEASE]
	at org.springframework.beans.factory.support.ConstructorResolver.autowireConstructor(ConstructorResolver.java:218) ~[spring-beans-5.1.5.RELEASE.jar:5.1.5.RELEASE]
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireConstructor(AbstractAutowireCapableBeanFactory.java:1325) ~[spring-beans-5.1.5.RELEASE.jar:5.1.5.RELEASE]
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1171) ~[spring-beans-5.1.5.RELEASE.jar:5.1.5.RELEASE]
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:555) ~[spring-beans-5.1.5.RELEASE.jar:5.1.5.RELEASE]
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:515) ~[spring-beans-5.1.5.RELEASE.jar:5.1.5.RELEASE]
	at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:320) ~[spring-beans-5.1.5.RELEASE.jar:5.1.5.RELEASE]
	at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222) ~[spring-beans-5.1.5.RELEASE.jar:5.1.5.RELEASE]
	at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:318) ~[spring-beans-5.1.5.RELEASE.jar:5.1.5.RELEASE]
	at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:199) ~[spring-beans-5.1.5.RELEASE.jar:5.1.5.RELEASE]
	at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:849) ~[spring-beans-5.1.5.RELEASE.jar:5.1.5.RELEASE]
	at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:877) ~[spring-context-5.1.5.RELEASE.jar:5.1.5.RELEASE]
	at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:549) ~[spring-context-5.1.5.RELEASE.jar:5.1.5.RELEASE]
	at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:142) ~[spring-boot-2.1.3.RELEASE.jar:2.1.3.RELEASE]
	at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:775) ~[spring-boot-2.1.3.RELEASE.jar:2.1.3.RELEASE]
	at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:397) ~[spring-boot-2.1.3.RELEASE.jar:2.1.3.RELEASE]
	at org.springframework.boot.SpringApplication.run(SpringApplication.java:316) ~[spring-boot-2.1.3.RELEASE.jar:2.1.3.RELEASE]
	at org.springframework.boot.SpringApplication.run(SpringApplication.java:1260) ~[spring-boot-2.1.3.RELEASE.jar:2.1.3.RELEASE]
	at org.springframework.boot.SpringApplication.run(SpringApplication.java:1248) ~[spring-boot-2.1.3.RELEASE.jar:2.1.3.RELEASE]
	at com.exp.HistoryServiceApplication.main(HistoryServiceApplication.java:18) ~[classes/:na]
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'eventRepository': Error setting property values; nested exception is org.springframework.beans.NotWritablePropertyException: Invalid property 'dynamoDBMapperConfig' of bean class [org.socialsignin.spring.data.dynamodb.repository.support.DynamoDBRepositoryFactoryBean]: Bean property 'dynamoDBMapperConfig' is not writable or has an invalid setter method. Does the parameter type of the setter match the return type of the getter?
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyPropertyValues(AbstractAutowireCapableBeanFactory.java:1702) ~[spring-beans-5.1.5.RELEASE.jar:5.1.5.RELEASE]
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1417) ~[spring-beans-5.1.5.RELEASE.jar:5.1.5.RELEASE]
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:592) ~[spring-beans-5.1.5.RELEASE.jar:5.1.5.RELEASE]
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:515) ~[spring-beans-5.1.5.RELEASE.jar:5.1.5.RELEASE]
	at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:320) ~[spring-beans-5.1.5.RELEASE.jar:5.1.5.RELEASE]
	at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222) ~[spring-beans-5.1.5.RELEASE.jar:5.1.5.RELEASE]
	at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:318) ~[spring-beans-5.1.5.RELEASE.jar:5.1.5.RELEASE]
	at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:199) ~[spring-beans-5.1.5.RELEASE.jar:5.1.5.RELEASE]
	at org.springframework.beans.factory.config.DependencyDescriptor.resolveCandidate(DependencyDescriptor.java:277) ~[spring-beans-5.1.5.RELEASE.jar:5.1.5.RELEASE]
	at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1247) ~[spring-beans-5.1.5.RELEASE.jar:5.1.5.RELEASE]
	at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1167) ~[spring-beans-5.1.5.RELEASE.jar:5.1.5.RELEASE]
	at org.springframework.beans.factory.support.ConstructorResolver.resolveAutowiredArgument(ConstructorResolver.java:857) ~[spring-beans-5.1.5.RELEASE.jar:5.1.5.RELEASE]
	at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:760) ~[spring-beans-5.1.5.RELEASE.jar:5.1.5.RELEASE]
	... 19 common frames omitted
Caused by: org.springframework.beans.NotWritablePropertyException: Invalid property 'dynamoDBMapperConfig' of bean class [org.socialsignin.spring.data.dynamodb.repository.support.DynamoDBRepositoryFactoryBean]: Bean property 'dynamoDBMapperConfig' is not writable or has an invalid setter method. Does the parameter type of the setter match the return type of the getter?
	at org.springframework.beans.BeanWrapperImpl.createNotWritablePropertyException(BeanWrapperImpl.java:243) ~[spring-beans-5.1.5.RELEASE.jar:5.1.5.RELEASE]
	at org.springframework.beans.AbstractNestablePropertyAccessor.processLocalProperty(AbstractNestablePropertyAccessor.java:426) ~[spring-beans-5.1.5.RELEASE.jar:5.1.5.RELEASE]
	at org.springframework.beans.AbstractNestablePropertyAccessor.setPropertyValue(AbstractNestablePropertyAccessor.java:278) ~[spring-beans-5.1.5.RELEASE.jar:5.1.5.RELEASE]
	at org.springframework.beans.AbstractNestablePropertyAccessor.setPropertyValue(AbstractNestablePropertyAccessor.java:266) ~[spring-beans-5.1.5.RELEASE.jar:5.1.5.RELEASE]
	at org.springframework.beans.AbstractPropertyAccessor.setPropertyValues(AbstractPropertyAccessor.java:97) ~[spring-beans-5.1.5.RELEASE.jar:5.1.5.RELEASE]
	at org.springframework.beans.AbstractPropertyAccessor.setPropertyValues(AbstractPropertyAccessor.java:77) ~[spring-beans-5.1.5.RELEASE.jar:5.1.5.RELEASE]
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyPropertyValues(AbstractAutowireCapableBeanFactory.java:1698) ~[spring-beans-5.1.5.RELEASE.jar:5.1.5.RELEASE]
	... 31 common frames omitted


Process finished with exit code 1```

naveentammineni avatar Mar 02 '19 20:03 naveentammineni

@naveentammineni

Explain to me how can I reproduce the error and I will try to fix it. I built a project with the fix I made and now my app works as expected.

You can, e.g., show your dynamodb config.

TY

tiagocpeixoto avatar Mar 03 '19 11:03 tiagocpeixoto

Hi @tiagocpeixoto,

I work with @naveentammineni. Here's a simple example repo that shows the problem: https://github.com/pluttrell/spring-data-dynamodb-5.1.0-issue.

To provide you some context, we're following this example to override the table names: https://github.com/derjust/spring-data-dynamodb/wiki/Alter-table-name-during-runtime.

In the example repo, if we run ./gradlew clean test using the 5.1.0 release or our build with PR#238 applied, we get an error identical to the original poster. If we run the SpringBootApp, we get the following:

Parameter 1 of method dynamoDBMapper in example.config.DynamoDbConfig required a single bean, but 2 were found:
	- dynamoDBMapperConfig: defined by method 'dynamoDBMapperConfig' in class path resource [example/config/DynamoDbConfig.class]
	- dynamoDB-DynamoDBMapperConfig: defined in null

It appears that the new model put in place for 5.1.0 doesn't properly take into account deployments with custom DynamoDBMapperConfig and DynamoDBMapper and creates a second instance of each.

If we mark both methods that provide those beans to temporarily work around this issue, and run the unit tests, we get the same issue as when we originally ran the unit tests. If I run the SpringBootApp, we get what @naveentammineni posted. Here's the root cause by:

Caused by: org.springframework.beans.NotWritablePropertyException: Invalid property 'dynamoDBMapperConfig' of bean class [org.socialsignin.spring.data.dynamodb.repository.support.DynamoDBRepositoryFactoryBean]: Bean property 'dynamoDBMapperConfig' is not writable or has an invalid setter method. Does the parameter type of the setter match the return type of the getter?
	at org.springframework.beans.BeanWrapperImpl.createNotWritablePropertyException(BeanWrapperImpl.java:243) ~[spring-beans-5.1.5.RELEASE.jar:5.1.5.RELEASE]
	at org.springframework.beans.AbstractNestablePropertyAccessor.processLocalProperty(AbstractNestablePropertyAccessor.java:426) ~[spring-beans-5.1.5.RELEASE.jar:5.1.5.RELEASE]
	at org.springframework.beans.AbstractNestablePropertyAccessor.setPropertyValue(AbstractNestablePropertyAccessor.java:278) ~[spring-beans-5.1.5.RELEASE.jar:5.1.5.RELEASE]
	at org.springframework.beans.AbstractNestablePropertyAccessor.setPropertyValue(AbstractNestablePropertyAccessor.java:266) ~[spring-beans-5.1.5.RELEASE.jar:5.1.5.RELEASE]
	at org.springframework.beans.AbstractPropertyAccessor.setPropertyValues(AbstractPropertyAccessor.java:97) ~[spring-beans-5.1.5.RELEASE.jar:5.1.5.RELEASE]
	at org.springframework.beans.AbstractPropertyAccessor.setPropertyValues(AbstractPropertyAccessor.java:77) ~[spring-beans-5.1.5.RELEASE.jar:5.1.5.RELEASE]
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyPropertyValues(AbstractAutowireCapableBeanFactory.java:1698) ~[spring-beans-5.1.5.RELEASE.jar:5.1.5.RELEASE]
	... 17 common frames omitted

If we remove dynamoDBMapperConfigRef = "dynamoDBMapperConfig" from example.config.DynamoDbConfig, the unit tests still fail as they have both previous times, but then the SpringBootApp does start up, but it's unclear if it's fully functional. But within the instructions on how to override the table names, it's called out that we need to include this.

Thanks.

pluttrell avatar Mar 05 '19 10:03 pluttrell

Keep an eye on #230 there is also a repo linked that shows this error: https://github.com/davidmelia/spring-data-dynamodb-bug

shexbeer avatar Mar 07 '19 15:03 shexbeer

@naveentammineni @pluttrell

I made a new fix. Please test it.

My tests with a custom DynamoDBMapperConfig (dev. table prefix) are now passing.

tiagocpeixoto avatar Mar 09 '19 14:03 tiagocpeixoto

Hi,

i tried @tiagocpeixoto fix and it actually solved the issue for me. So i can confirm that your PR fixes the issue!

Please solve the merge conflicts in the PR Then please make this change available through mvn repository.

Best regards,

shexbeer avatar Mar 19 '19 11:03 shexbeer

Hey guys, any prediction for when this PR will be merged? This is being a blocker for us.

naderfares avatar Mar 22 '19 03:03 naderfares

Having this same issue, any update on when the fix will be available in maven?

VictorNordlund avatar Mar 29 '19 07:03 VictorNordlund

Thanks for the great work! Is there any ETA on the 5.1.1 release for this?

drissamri avatar Apr 02 '19 13:04 drissamri

Any updates here?

shexbeer avatar Apr 10 '19 07:04 shexbeer

Push. Who can accept @tiagocpeixoto PR? We are blocked and need this fix! Maybe @derjust

shexbeer avatar May 08 '19 07:05 shexbeer

push. its really important Maybe @derjust can have a look into the mentioned PR

shexbeer avatar May 16 '19 07:05 shexbeer

Hope there can be some progress, and a new release here soon. It is a blocker

maccamlc avatar May 21 '19 05:05 maccamlc

This now works for me.

It seems to have been fixed in the Spring Framework (see https://github.com/spring-projects/spring-framework/issues/22409).

This was linked from https://github.com/spring-projects/spring-boot/issues/15898 in Spring Boot, and fixed in Spring Boot 2.1.4.RELEASE (see changelog in https://github.com/spring-projects/spring-boot/releases/tag/v2.1.4.RELEASE)

I've upgraded to Spring Boot 2.1.5.RELEASE, and can now test with a RANDOM PORT set as WebEnvironment.

It appears that it is generally considered bad practice for a FactoryBean to not have a default constructor, but can move forward now :)

maccamlc avatar Jun 05 '19 06:06 maccamlc