I am trying to add custom behavior to all repositories in my spring boot application only with annotations. Official documentation deals with JPA and not for MongoDB.
I have not created any custom methods yet as I want to check whether the default is working fine.
My code is as follows:
src/main/java/com/test/shipper/database:
MongoConfig.java
src/main/java/com/test/shipper/modal:
Shipper.java
src/main/java/com/test/shipper/repository:
BaseRepositoryFactoryBean.java
BaseRepositoryImpl.java
BaseRepository.java
ShipperRepository.java
src/main/java/com/test/shipper/service:
ShipperService.java
ShipperService.java
public class ShipperService {
@Autowired
private ShipperRepository repository;
public Shipper createShipper(Shipper shipper){
repository.deleteAll();
Shipper shipper1 = new Shipper("123","shipper123");
repository.insert(shipper1);
Shipper shipper2 = new Shipper("234","shipper234");
repository.insert(shipper2);
System.out.println("Find All!!");
List shippers = repository.findAll();
for (Shipper car: shippers) {System.out.println(car);}
repository.delete(shipper2.getShipperId());
shippers = repository.findAll();
for (Shipper car: shippers) {
System.out.println(car);
}
return null;
}
}
MongoConfig.java
@Configuration
@EnableMongoRepositories(basePackages = "com.test.shipper",
repositoryFactoryBeanClass = com.test.shipper.repository.BaseRepositoryFactoryBean.class)
public class MongoConfig extends AbstractMongoConfiguration {
@Value("test")
private String dbName;
@Value("127.0.0.1")
private String host;
@Value("27017")
private int port;
@Override
protected String getDatabaseName() {
return dbName;
}
@Bean
@Override
public Mongo mongo() throws Exception {
return new MongoClient(host, port);
}
@Bean
public MongoTemplate mongoTemplate() throws Exception {
return new MongoTemplate(mongo(), dbName);
}
}
BaseRepository.java
@NoRepositoryBean
public interface BaseRepository<T, ID extends Serializable>
extends MongoRepository<T, ID>
{
}
BaseRepositoryImpl.java
@NoRepositoryBean
public class BaseRepositoryImpl
extends SimpleMongoRepository implements BaseRepository
{
private MongoOperations mongoOperations;
public BaseRepositoryImpl(MongoEntityInformation metadata,
MongoOperations mongoOperations) {
super(metadata, mongoOperations);
this.mongoOperations = mongoOperations;
}
}
BaseRepositoryFactoryBean.java
public class BaseRepositoryFactoryBean, T, I extends Serializable>
extends MongoRepositoryFactoryBean {
public BaseRepositoryFactoryBean(Class repositoryInterface) {
super(repositoryInterface);
}
@Override
protected RepositoryFactorySupport getFactoryInstance(
MongoOperations operations) {
return new BaseMongoRepositoryFactory( operations );
}
private static class BaseMongoRepositoryFactory
extends MongoRepositoryFactory {
private MongoOperations mongo;
public BaseMongoRepositoryFactory(MongoOperations mongoOperations) {
super(mongoOperations);
this.mongo = mongoOperations;
}
@SuppressWarnings("unchecked")
protected Object getTargetRepository(RepositoryMetadata metadata) {
TypeInformation information = ClassTypeInformation.from((Class)metadata.getDomainType());
MongoPersistentEntity pe = new BasicMongoPersistentEntity(information);
MongoEntityInformation mongometa =
new MappingMongoEntityInformation(pe);
return new BaseRepositoryImpl( mongometa, mongo);
}
protected Class getRepositoryBaseClass(RepositoryMetadata metadata) {
return BaseRepository.class;
}
}
}
ShipperRepository.java
@Repository
public interface ShipperRepository
extends BaseRepository{
}
Shipper.java
@Document(collection = "shipper")
public class Shipper{
@Id
private String shipperId;
private String shipperName;
public Shipper() {
}
public Shipper(String shipperId, String shipperName) {
this.shipperId = shipperId;
this.shipperName = shipperName;
}
public String getShipperId() {
return shipperId;
}
public void setShipperId(String shipperId) {
this.shipperId = shipperId;
}
public String getShipperName() {
return shipperName;
}
public void setShipperName(String shipperName) {
this.shipperName = shipperName;
}
}
When the application starts I am getting the following exception.
Error starting ApplicationContext. To display the auto-configuration report re-run your application with 'debug' enabled.
2017-08-06 23:08:26.849 ERROR 12828 --- [ main] o.s.boot.SpringApplication : Application startup failed
org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'shipperService': Unsatisfied dependency expressed through field 'repository'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'shipperRepository': Invocation of init method failed; nested exception is java.lang.IllegalStateException: No suitable constructor found on interface com.test.shipper.repository.BaseRepository to match the given arguments: [class org.springframework.data.mongodb.repository.support.MappingMongoEntityInformation, class org.springframework.data.mongodb.core.MongoTemplate]. Make sure you implement a constructor taking these
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:588) ~[spring-beans-4.3.10.RELEASE.jar!/:4.3.10.RELEASE]
at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:88) ~[spring-beans-4.3.10.RELEASE.jar!/:4.3.10.RELEASE]
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:366) ~[spring-beans-4.3.10.RELEASE.jar!/:4.3.10.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1264) ~[spring-beans-4.3.10.RELEASE.jar!/:4.3.10.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:553) ~[spring-beans-4.3.10.RELEASE.jar!/:4.3.10.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:483) ~[spring-beans-4.3.10.RELEASE.jar!/:4.3.10.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306) ~[spring-beans-4.3.10.RELEASE.jar!/:4.3.10.RELEASE]
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230) ~[spring-beans-4.3.10.RELEASE.jar!/:4.3.10.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302) ~[spring-beans-4.3.10.RELEASE.jar!/:4.3.10.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197) ~[spring-beans-4.3.10.RELEASE.jar!/:4.3.10.RELEASE]
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:761) ~[spring-beans-4.3.10.RELEASE.jar!/:4.3.10.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:867) ~[spring-context-4.3.10.RELEASE.jar!/:4.3.10.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:543) ~[spring-context-4.3.10.RELEASE.jar!/:4.3.10.RELEASE]
at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.refresh(EmbeddedWebApplicationContext.java:122) ~[spring-boot-1.5.6.RELEASE.jar!/:1.5.6.RELEASE]
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:693) [spring-boot-1.5.6.RELEASE.jar!/:1.5.6.RELEASE]
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:360) [spring-boot-1.5.6.RELEASE.jar!/:1.5.6.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:303) [spring-boot-1.5.6.RELEASE.jar!/:1.5.6.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1118) [spring-boot-1.5.6.RELEASE.jar!/:1.5.6.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1107) [spring-boot-1.5.6.RELEASE.jar!/:1.5.6.RELEASE]
at com.test.shipper.ShipperApplication.main(ShipperApplication.java:12) [classes!/:0.0.1-SNAPSHOT]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_131]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_131]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_131]
at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_131]
at org.springframework.boot.loader.MainMethodRunner.run(MainMethodRunner.java:48) [shipper_microservice-0.0.1-SNAPSHOT.jar:0.0.1-SNAPSHOT]
at org.springframework.boot.loader.Launcher.launch(Launcher.java:87) [shipper_microservice-0.0.1-SNAPSHOT.jar:0.0.1-SNAPSHOT]
at org.springframework.boot.loader.Launcher.launch(Launcher.java:50) [shipper_microservice-0.0.1-SNAPSHOT.jar:0.0.1-SNAPSHOT]
at org.springframework.boot.loader.JarLauncher.main(JarLauncher.java:51) [shipper_microservice-0.0.1-SNAPSHOT.jar:0.0.1-SNAPSHOT]
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'shipperRepository': Invocation of init method failed; nested exception is java.lang.IllegalStateException: No suitable constructor found on interface com.test.shipper.repository.BaseRepository to match the given arguments: [class org.springframework.data.mongodb.repository.support.MappingMongoEntityInformation, class org.springframework.data.mongodb.core.MongoTemplate]. Make sure you implement a constructor taking these
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1628) ~[spring-beans-4.3.10.RELEASE.jar!/:4.3.10.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:555) ~[spring-beans-4.3.10.RELEASE.jar!/:4.3.10.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:483) ~[spring-beans-4.3.10.RELEASE.jar!/:4.3.10.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306) ~[spring-beans-4.3.10.RELEASE.jar!/:4.3.10.RELEASE]
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230) ~[spring-beans-4.3.10.RELEASE.jar!/:4.3.10.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302) ~[spring-beans-4.3.10.RELEASE.jar!/:4.3.10.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:202) ~[spring-beans-4.3.10.RELEASE.jar!/:4.3.10.RELEASE]
at org.springframework.beans.factory.config.DependencyDescriptor.resolveCandidate(DependencyDescriptor.java:208) ~[spring-beans-4.3.10.RELEASE.jar!/:4.3.10.RELEASE]
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1138) ~[spring-beans-4.3.10.RELEASE.jar!/:4.3.10.RELEASE]
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1066) ~[spring-beans-4.3.10.RELEASE.jar!/:4.3.10.RELEASE]
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:585) ~[spring-beans-4.3.10.RELEASE.jar!/:4.3.10.RELEASE]
... 27 common frames omitted
Caused by: java.lang.IllegalStateException: No suitable constructor found on interface com.test.shipper.repository.BaseRepository to match the given arguments: [class org.springframework.data.mongodb.repository.support.MappingMongoEntityInformation, class org.springframework.data.mongodb.core.MongoTemplate]. Make sure you implement a constructor taking these
at org.springframework.data.repository.core.support.RepositoryFactorySupport.getTargetRepositoryViaReflection(RepositoryFactorySupport.java:360) ~[spring-data-commons-1.13.6.RELEASE.jar!/:na]
at org.springframework.data.mongodb.repository.support.MongoRepositoryFactory.getTargetRepository(MongoRepositoryFactory.java:98) ~[spring-data-mongodb-1.10.6.RELEASE.jar!/:na]
at org.springframework.data.repository.core.support.RepositoryFactorySupport.getRepository(RepositoryFactorySupport.java:199) ~[spring-data-commons-1.13.6.RELEASE.jar!/:na]
at org.springframework.data.repository.core.support.RepositoryFactoryBeanSupport.initAndReturn(RepositoryFactoryBeanSupport.java:277) ~[spring-data-commons-1.13.6.RELEASE.jar!/:na]
at org.springframework.data.repository.core.support.RepositoryFactoryBeanSupport.afterPropertiesSet(RepositoryFactoryBeanSupport.java:263) ~[spring-data-commons-1.13.6.RELEASE.jar!/:na]
at org.springframework.data.mongodb.repository.support.MongoRepositoryFactoryBean.afterPropertiesSet(MongoRepositoryFactoryBean.java:117) ~[spring-data-mongodb-1.10.6.RELEASE.jar!/:na]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1687) ~[spring-beans-4.3.10.RELEASE.jar!/:4.3.10.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1624) ~[spring-beans-4.3.10.RELEASE.jar!/:4.3.10.RELEASE]
... 37 common frames omitted
</code></pre>
What could be the issue?