Cannot resolve reference to bean 'mongoTemplate' while setting bean property 'mongoOperations' - java

there are few answers to the question already. But none of them works for me.
I can't figure it out for the life of me why the error is coming.
Following are the approaches I tried:
using AbstractMongoConfiguration
Manually registering the mongoTemplate bean with ApplicationContext
Whenever I try to run my test during maven build or while deploying on tomcat error below comes up
Here is the configuration.
package com.fordit.project.config;
#Configuration
#EnableMongoRepositories(basePackages = "com.company.project")
#ComponentScan(basePackages = "com.company.project")
public class ProjectConfiguration {
#Value("${project.db.driver_class}")
private String driverClassname;
#Value("${project.db.connection_string}")
private String connectionString;
#Bean
public DataSource dataSource() throws PropertyVetoException {
Properties mysqlProperties = new Properties();
mysqlProperties.setProperty("characterEncoding", "UTF-8");
mysqlProperties.setProperty("useUnicode", "true");
ComboPooledDataSource cpds = new ComboPooledDataSource();
cpds.setProperties(mysqlProperties);
cpds.setDriverClass(driverClassname);
cpds.setJdbcUrl(connectionString);
cpds.setAcquireIncrement(2);
return cpds;
}
#Bean
public static PropertyPlaceholderConfigurer getPropertyPlaceholderConfigurer() throws IOException {
PropertyPlaceholderConfigurer ppc = new PropertyPlaceholderConfigurer();
ResourceLoader resourceLoader = new PathMatchingResourcePatternResolver();
ppc.setLocations(
resourceLoader.getResource(System.getProperty("PROJECT_CONFIGURATION_FILE")));
return ppc;
}
#Bean
public static RoleHierarchy roleHierarchy() {
String roleHierarchyStringRepresentation
= Role.ROLE_ADMIN + " > " + Role.ROLE_FIRM + "\n"
+ Role.ROLE_FIRM + " = " + Role.ROLE_LAWYER+ "= "+Role.ROLE_USER;
//logger.info("Registered Role Hierarchy: \n{}", roleHierarchyStringRepresentation);
RoleHierarchyImpl roleHierarchy = new RoleHierarchyImpl();
roleHierarchy.setHierarchy(roleHierarchyStringRepresentation);
return roleHierarchy;
}
}
Mongo Configuration:
#Configuration
#ComponentScan(basePackages = "com.company.project")
#Profile("container")
public class MongoDBConfiguration extends AbstractMongoConfiguration {
#Value("${project.mongodb.hostname}")
private String host;
#Value("${project.mongodb.port}")
private Integer port;
#Value("${project.mongodb.name}")
private String db;
#Value("${project.mongodb.username}")
private String username;
#Value("${project.mongodb.password}")
private String password;
#Value("${project.mongodb.authenticationDB}")
private String authDB;
#Bean
public MongoTemplate mongoTemplate()
throws UnknownHostException, java.net.UnknownHostException {
return new MongoTemplate(
new SimpleMongoDbFactory(
mongoClient(),
getDatabaseName()
)
);
}
#Override
#Bean
public MongoClient mongoClient() {
MongoClient mongoClient = null;
try {
mongoClient = new MongoClient(
new ServerAddress(host, port),
Collections.singletonList(
MongoCredential.createMongoCRCredential(
username,
authDB,
password.toCharArray()
)
)
);
} catch (java.net.UnknownHostException ex) {
Logger.getLogger(MongoDBConfiguration.class.getName()).log(Level.SEVERE, null, ex);
}
return mongoClient;
}
#Override
protected String getDatabaseName() {
return db;
}
}
Error log:
Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'forumDAL' defined in file [/home/ashay/projects/kuber/target/classes/com/fordit/kuber/forum/ForumDAL.class]: Unsatisfied dependency expressed through constructor parameter 0; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'forumRepository': Cannot resolve reference to bean 'mongoTemplate' while setting bean property 'mongoOperations'; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'mongoTemplate' available
at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:729)
at org.springframework.beans.factory.support.ConstructorResolver.autowireConstructor(ConstructorResolver.java:192)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireConstructor(AbstractAutowireCapableBeanFactory.java:1270)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1127)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:541)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:501)
at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:317)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:228)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:315)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:199)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:760)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:869)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:550)
at org.springframework.test.context.support.AbstractGenericContextLoader.loadContext(AbstractGenericContextLoader.java:128)
at org.springframework.test.context.support.AbstractGenericContextLoader.loadContext(AbstractGenericContextLoader.java:60)
at org.springframework.test.context.support.AbstractDelegatingSmartContextLoader.delegateLoading(AbstractDelegatingSmartContextLoader.java:107)
at org.springframework.test.context.support.AbstractDelegatingSmartContextLoader.loadContext(AbstractDelegatingSmartContextLoader.java:243)
at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContextInternal(DefaultCacheAwareContextLoaderDelegate.java:99)
at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:117)
... 26 more

Get rid of the Profile("container") in MongoDBConfiguration.
Explanation: Because the #Profile is there, that means that that class will not be instantiated by Spring unless you are running Spring with that profile. My guess is that you are not setting spring.profiles.active property to "container" when you run your application via Tomcat or during your integration testing.
If you want to leave the #Profile("container") there then just make sure you set the profile to "container". There are multiple ways to do this. One quick easy way is to use Java system properties, e.g. -Dspring.profiles.active=container, when you execute your integration tests or run your application in Tomcat.

Related

Quartz Spring Boot There is no DataSource named 'dataSource'

I have the following quartz.properties:
org.quartz.jobStore.class=org.quartz.impl.jdbcjobstore.JobStoreTX
org.quartz.jobStore.dataSource=dataSource
org.quartz.jobStore.driverDelegateClass=org.quartz.impl.jdbcjobstore.PostgreSQLDelegate
org.quartz.jobStore.tablePrefix=qrtz_
org.quartz.threadPool.threadCount=1
org.quartz.scheduler.skipUpdateCheck=true
org.quartz.plugin.triggerHistory.class=org.quartz.plugins.history.LoggingTriggerHistoryPlugin
Also, I added QuartzConfiguration:
#Configuration
#EnableScheduling
public class QuartzConfiguration {
public static final String CONTEXT_KEY = "applicationContext";
#Autowired
private DataSource dataSource;
#Bean
public SchedulerFactoryBean schedulerFactoryBean() {
SchedulerFactoryBean scheduler = new SchedulerFactoryBean();
scheduler.setApplicationContextSchedulerContextKey("applicationContext");
scheduler.setConfigLocation(new ClassPathResource("quartz.properties"));
scheduler.setDataSource(dataSource);
scheduler.setWaitForJobsToCompleteOnShutdown(true);
return scheduler;
}
}
In the application.properties I have defined:
#PostgreSQL
spring.datasource.url=${postgresql.datasource.url}
spring.datasource.username=${postgresql.datasource.username}
spring.datasource.password=${postgresql.datasource.password}
Right now, during start up the application fails with the following exception:
Caused by: org.quartz.JobPersistenceException: Failed to obtain DB connection from data source 'dataSource': java.sql.SQLException: There is no DataSource named 'dataSource' [See nested exception: java.sql.SQLException: There is no DataSource named 'dataSource']
at org.quartz.impl.jdbcjobstore.JobStoreSupport.getConnection(JobStoreSupport.java:783)
at org.quartz.impl.jdbcjobstore.JobStoreTX.getNonManagedTXConnection(JobStoreTX.java:71)
at org.quartz.impl.jdbcjobstore.JobStoreSupport.executeInNonManagedTXLock(JobStoreSupport.java:3861)
at org.quartz.impl.jdbcjobstore.JobStoreSupport.recoverJobs(JobStoreSupport.java:839)
at org.quartz.impl.jdbcjobstore.JobStoreSupport.schedulerStarted(JobStoreSupport.java:695)
... 45 more
Caused by: java.sql.SQLException: There is no DataSource named 'dataSource'
at org.quartz.utils.DBConnectionManager.getConnection(DBConnectionManager.java:104)
at org.quartz.impl.jdbcjobstore.JobStoreSupport.getConnection(JobStoreSupport.java:780)
... 49 more
What am I doing wrong and how to provide a correct DataSource to the org.quartz.jobStore.dataSource ?
Two options:
create a configuration bean that specifically creates you DataSource.
#Bean
public DataSource getDataSource()
{
DataSourceBuilder dataSourceBuilder = DataSourceBuilder.create();
dataSourceBuilder.driverClassName("org.h2.Driver");
dataSourceBuilder.url("jdbc:h2:file:C:/temp/test");
dataSourceBuilder.username("sa");
dataSourceBuilder.password("");
return dataSourceBuilder.build();
}
You can alternatively use JNDI, use the spring.datasource.jndi-name
see also

org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type 'org.apache.ibatis.session.SqlSessionFactory'

I know there are many examples over internet for the same problem. But what I am trying to get help is on architecture level.
I have a simple spring project where in I have one configuration class.I am trying to configure two datasources
(distDataSource, shipmentDataSource). I have two separate classes for two data sources (MyBatisDISTDataSource , MyBatisShipmentDataSource) mentioned below.
These two datasorces are working fine separately, but when I am trying to execute it together I get exception on console.
Console Exception Log
Exception in thread "main"
org.springframework.beans.factory.UnsatisfiedDependencyException:
Error creating bean with name 'distDAOImpl': Unsatisfied dependency
expressed through field 'distMapper'; nested exception is
org.springframework.beans.factory.UnsatisfiedDependencyException:
Error creating bean with name 'distMapper' defined in file
[D:\eclipse\ShippingModule\shipment-module-v2\CustEquip-CourierShipmentService-PickupSvc\target\classes\com\shipment\mapper\DistMapper.class]: Unsatisfied dependency expressed through bean property
'sqlSessionFactory'; nested exception is
org.springframework.beans.factory.NoUniqueBeanDefinitionException: No
qualifying bean of type 'org.apache.ibatis.session.SqlSessionFactory'
available: expected single matching bean but found 2:
distSqlSessionFactory,shipmentSqlSessionFactory at
org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:588)
at
org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:88)
at
org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:366)
at
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1264)
at
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:553)
at
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:483)
at
org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306)
at
org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
at
org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302)
at
org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197)
at
org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:761)
at
org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:867)
at
org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:543)
at
org.springframework.context.annotation.AnnotationConfigApplicationContext.(AnnotationConfigApplicationContext.java:84)
at
com.telus.shipment.app.starter.SchedulePickup.main(SchedulePickup.java:11)
Caused by:
org.springframework.beans.factory.UnsatisfiedDependencyException:
Error creating bean with name 'distMapper' defined in file
[D:\eclipse\ShippingModule\shipment-module-v2\CustEquip-CourierShipmentService-PickupSvc\target\classes\com\shipment\mapper\DistMapper.class]: Unsatisfied dependency expressed through bean property
'sqlSessionFactory'; nested exception is
org.springframework.beans.factory.NoUniqueBeanDefinitionException: No
qualifying bean of type 'org.apache.ibatis.session.SqlSessionFactory'
available: expected single matching bean but found 2:
distSqlSessionFactory,shipmentSqlSessionFactory at
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireByType(AbstractAutowireCapableBeanFactory.java:1357)
at
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1249)
at
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:553)
at
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:483)
at
org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306)
at
org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
at
org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302)
at
org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:202)
at
org.springframework.beans.factory.config.DependencyDescriptor.resolveCandidate(DependencyDescriptor.java:208)
at
org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1138)
at
org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1066)
at
org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:585)
... 14 more Caused by:
org.springframework.beans.factory.NoUniqueBeanDefinitionException: No
qualifying bean of type 'org.apache.ibatis.session.SqlSessionFactory'
available: expected single matching bean but found 2:
distSqlSessionFactory,shipmentSqlSessionFactory at
org.springframework.beans.factory.config.DependencyDescriptor.resolveNotUnique(DependencyDescriptor.java:173)
at
org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1116)
at
org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1066)
at
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireByType(AbstractAutowireCapableBeanFactory.java:1342)
... 25 more
Configuration Class
#Component
#Configuration
#Profile("local")
public class EnvironmentConfigLocal implements EnvironmentConfig {
#Autowired #Qualifier("DISTDataSource") private MyBatisDISTDataSource distDataSource;
#Autowired #Qualifier("ShipmentDataSource") private MyBatisShipmentDataSource shipmentDataSource;
#PostConstruct
public void postConstruct() {
System.out.println("Selected Profile : Local");
}
#Bean
public static PropertySourcesPlaceholderConfigurer dataProperties(final Environment environment) {
final PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer = new PropertySourcesPlaceholderConfigurer();
final YamlPropertiesFactoryBean yaml = new YamlPropertiesFactoryBean();
final SpringProfileDocumentMatcher matcher = new SpringProfileDocumentMatcher();
matcher.addActiveProfiles(environment.getActiveProfiles());
yaml.setDocumentMatchers(matcher);
yaml.setResources(new ClassPathResource("application.yaml"));
propertySourcesPlaceholderConfigurer.setProperties(yaml.getObject());
return propertySourcesPlaceholderConfigurer;
}
#Bean
public DataSourceTransactionManager distTransactionManager() throws SQLException {
return new DataSourceTransactionManager(distDataSource);
}
#Bean
public DataSourceTransactionManager shipmentTransactionManager() throws SQLException {
return new DataSourceTransactionManager(shipmentDataSource);
}
#Bean
#Override
public SqlSessionFactory distSqlSessionFactory() throws Exception {
SqlSessionFactoryBean distSessionFactory = new SqlSessionFactoryBean();
distSessionFactory.setDataSource(distDataSource);
return distSessionFactory.getObject();
}
#Bean
#Override
public SqlSessionFactory shipmentSqlSessionFactory() throws Exception {
SqlSessionFactoryBean shipmentSessionFactory = new SqlSessionFactoryBean();
shipmentSessionFactory.setDataSource(shipmentDataSource);
return shipmentSessionFactory.getObject();
}
}
MyBatisDISTDataSource
#Component
#Qualifier("DISTDataSource")
public class MyBatisDISTDataSource extends PooledDataSource {
#Value("${dist.db.poolMaximumActiveConnections}") int poolMaximumActiveConnections;
#Value("${dist.db.poolMaximumIdleConnections}") int poolMaximumIdleConnections;
public MyBatisDISTDataSource(
#Value("${dist.db.driver-class}") String driver,
#Value("${dist.db.url}") String url,
#Value("${dist.db.user}") String username,
#Value("${dist.db.password}") String password) {
super(driver, url, username, password);
System.out.println("DIST DB Attr: \n\t"
+driver+"\n\t"
+url+"\n\t"
+username+"\n\t"
+password+"\n\t");
}
#PostConstruct
private void setDataSourceProperties() {
this.setPoolMaximumActiveConnections(poolMaximumActiveConnections);
this.setPoolMaximumIdleConnections(poolMaximumIdleConnections);
}
}
MyBatisShipmentDataSource
#Component
#Qualifier("ShipmentDataSource")
public class MyBatisShipmentDataSource extends PooledDataSource {
#Value("${shipment.db.poolMaximumActiveConnections}") int poolMaximumActiveConnections;
#Value("${shipment.db.poolMaximumIdleConnections}") int poolMaximumIdleConnections;
public MyBatisShipmentDataSource(
#Value("${shipment.db.driver-class}") String driver,
#Value("${shipment.db.url}") String url,
#Value("${shipment.db.user}") String username,
#Value("${shipment.db.password}") String password) {
super(driver, url, username, password);
System.out.println("Shipment DB Attr: \n\t"
+driver+"\n\t"
+url+"\n\t"
+username+"\n\t"
+password+"\n\t");
}
#PostConstruct
private void setDataSourceProperties() {
this.setPoolMaximumActiveConnections(poolMaximumActiveConnections);
this.setPoolMaximumIdleConnections(poolMaximumIdleConnections);
}
}
DistMapper
#Mapper
#Component
public interface DistMapper {
#Select({"select * "
+ "from CONTACT_ADDRESS CA, ADDRESS A"
+ "where CONTACTING_ID = '10001134' "
+ "and PROVINCE_CD ='ON' "
+ "and STREET_NUMBER = '15'"})
#Results({#Result(column = "CONTACTING_ID", property = "contactingId", jdbcType = JdbcType.DECIMAL)})
public List<OutletAddress> findAddressByOutletId();
}
ShipmentMapper
#Mapper
#Component
public interface ShipmentMapper {
#Select({"select C.CONTACT_ID "
+ "from SHIPMENT_EVENT_TRACKING SE, SHIPMENT S, CONTACT_ADDR CA, CONTACT C "
+ "where SE.EVENT_CD = 'PICKUP' "
+ "and SE.SHIPMENT_ID = s.shipment_id "
+ "and S.SENDER_ADDR_ID = CA.CONTACT_ADDR_ID "
+ "and CA.CONTACT_ID = c.contact_id "
+ "and C.GROUP_CD = 'OT' "
+ "and SE.EVENT_OCCURRED_IND = 'N' "
+ "and S.CREATION_TS >= (select CURRENT_TIMESTAMP - interval '30' day from dual)"
+ "and S.SCHEDULE_PICKUP_IND = 'Y'"})
#Results({
#Result(column = "CONTACT_ID", property = "contactId", jdbcType = JdbcType.DECIMAL)})
public CopyOnWriteArrayList<EligibleShipment> findShipmentsByOutlet();
}
#Primary on one of the SqlSessionFactory bean solved my problem.
#Bean
#Primary
#Override
public SqlSessionFactory sqlSessionFactory2() throws Exception {
SqlSessionFactoryBean sessionFactory2 = new SqlSessionFactoryBean();
sessionFactory2.setDataSource(dataSource2);
return sessionFactory2.getObject();
}
With spring-mybatis you either register mappers one by one or you use mappers scanning.
If you are registering mappers manually make sure you pass correct SqlSessionFactory to every mapper. If you don't do this spring will try to autowire SqlSessionFactory and because you have two of them you would get the error that no single bean found.
If you are using scanning for mappers specify parameters for it so that appropriate mappers are using correct SqlSessionFactory.
One way to do that is by placing mappers that should use different DataSources to different packages. In this case you need to create two MapperScannerConfigurer beans like this (assuming that mappers are in com.mycompany.myapp.distMappersPackage and com.mycompany.myapp.shipmentMappersPackage):
#Bean
public MapperScannerConfigurer distMapperScannerConfigurer() throws Exception {
MapperScannerConfigurer configurer = new MapperScannerConfigurer();
configurer.setBasePackage("com.mycompany.myapp.distMappersPackage");
configurer.setSqlSessionFactoryBeanName("distSqlSessionFactory");
return configurer;
}
#Bean
public MapperScannerConfigurer shipmentMapperScannerConfigurer() throws Exception {
MapperScannerConfigurer configurer = new MapperScannerConfigurer();
configurer.setBasePackage("com.mycompany.myapp.shipmentMappersPackage");
configurer.setSqlSessionFactoryBeanName("shipmentSqlSessionFactory");
return configurer;
}
Alternatively, you can create two different annotation and use them on mappers like this:
#DistMapperMarker
public interface DistMapper {
...
}
#ShipmentMapperMarker
public interface ShipmentMapper {
...
}
In this case mappers can be in one package but you specify annotationClass on MapperScannerConfigurer:
#Bean
public MapperScannerConfigurer distMapperScannerConfigurer() throws Exception {
MapperScannerConfigurer configurer = new MapperScannerConfigurer();
configurer.setAnnotationClass(DistMapperMarker.class);
configurer.setSqlSessionFactoryBeanName("distSqlSessionFactory");
return configurer;
}
#Bean
public MapperScannerConfigurer shipmentMapperScannerConfigurer() throws Exception {
MapperScannerConfigurer configurer = new MapperScannerConfigurer();
configurer.setAnnotationClass(ShipmentMapperMarker.class);
configurer.setSqlSessionFactoryBeanName("shipmentSqlSessionFactory");
return configurer;
}
For java base spring configuration you can also try to use MapperScan and specify parameters as attributes to it. This would require you to split spring configuration into at least two classes. I haven't used this approach so I'm not sure if it work fine.

Spring batch : Error creating bean with name , Gradle, Mongodb

My Application will not start. gives me an error creating a bean with the name of my file. I've searched and found similar posts to this question but they didnt seem to pertain to my error so I am hoping someone can find what may be causing this file to fail. Also, I am at a cross between two methods. Do I use the FlatFileReader or MomgoItemreader? I just need to retrieve two things from the DB firstname and lastname. I need to read the db and then write it to a file which I havent done yet. Any help would be greatly appreciated.
***************************
APPLICATION FAILED TO START
***************************
Description:
Failed to configure a DataSource: 'url' attribute is not specified and no embedded datasource could be configured.
Reason: Failed to determine a suitable driver class
Here is my class
#Configuration
#EnableBatchProcessing
public class PaymentPortalJob {
private static final Logger LOG =
LoggerFactory.getLogger(PaymentPortalJob.class);
#SuppressWarnings("unused")
#Autowired
private JobBuilderFactory jobBuilderFactory;
#SuppressWarnings("unused")
#Autowired
private StepBuilderFactory stepBuilderFactory;
#Autowired
private PaymentAuditRepository paymentAuditRepository;
// #Bean
// public FlatFileItemReader<PaymentAudit> PaymentPortalReader() {
// LOG.info("Inside PaymentPortalReader Method {}", "");
// return new FlatFileItemReaderBuilder<PaymentAudit>
().name("PaymentPortalReader")
// .delimited().names(new String[] { "rxFname", "rxLname" })
// .fieldSetMapper(new BeanWrapperFieldSetMapper<PaymentAudit>
() {
// {
// setTargetType(PaymentAudit.class);
// }
// }).build();
//
// }
#Bean
public ItemReader<PaymentAudit> reader() {
LOG.info("inside of ItemReader");
MongoItemReader<PaymentAudit> reader = new MongoItemReader<PaymentAudit>();
try {
reader.setTemplate(mongoTemplate());
} catch (Exception e) {
LOG.error(e.toString());
}
reader.setCollection("local");
return reader();
}
#Bean
public ItemProcessor<PaymentAudit, PaymentAudit> processor() {
return new PaymentPortalNOSQLProcessor();
}
#Bean
public ItemWriter<PaymentAudit> writer() {
MongoItemWriter<PaymentAudit> writer = new MongoItemWriter<PaymentAudit>();
try {
writer.setTemplate(mongoTemplate());
} catch (Exception e) {
LOG.error(e.toString());
}
writer.setCollection("paymentPortal");
return writer;
}
#Bean
Job job(JobBuilderFactory jbf, StepBuilderFactory sbf, ItemReader<? extends PaymentAudit> ir,
ItemWriter<? super PaymentAudit> iw) {
Step s1 = sbf.get("file-db").<PaymentAudit, PaymentAudit>chunk(100).reader(ir).writer(iw).build();
return jbf.get("etl").incrementer(new RunIdIncrementer()).start(s1).build();
}
#Bean
public MongoDbFactory mongoDbFactory() throws Exception {
return new SimpleMongoDbFactory(new MongoClient(), "local");
}
#Bean
public MongoTemplate mongoTemplate() throws Exception {
MongoTemplate mongoTemplate = new MongoTemplate(mongoDbFactory());
return mongoTemplate;
}
}
appplication.yml
mongodb:
databasePort: xxxxx
databaseName: local
spring:
data:
mongodb:
host: localhost
port: xxxxx
profiles:
active: local
batch:
job:
enabled: true
Processor:
package com.spring_batchjob.job.item;
import org.springframework.batch.item.ItemProcessor;
import com.spring_batchjob.bean.PaymentAudit;
public class PaymentPortalNOSQLProcessor implements
ItemProcessor<PaymentAudit, PaymentAudit> {
#Override
public PaymentAudit process(PaymentAudit bean) throws Exception {
return bean;
}
}
repo:
package com.spring_batchjob.repository;
import java.time.LocalDateTime;
import java.util.List;
import org.springframework.data.mongodb.repository.MongoRepository;
import org.springframework.stereotype.Repository;
import com.spring_batchjob.bean.PaymentAudit;
#Repository
public interface PaymentAuditRepository extends
MongoRepository<PaymentAudit, String> {
// List<PaymentAudit> findByCreateDttmBetween(LocalDateTime createStart,
LocalDateTime createEnd);
List<PaymentAudit> findByRxFNameAndRxLName(String rxFName, String
rxLName);
}
Error after running app:
2018-10-26 13:26:34.256 WARN 16376 --- [ restartedMain]
ConfigServletWebServerApplicationContext : Exception encountered during
context initialization - cancelling refresh attempt:
org.springframework.beans.factory.UnsatisfiedDependencyException: Error
creating bean with name 'paymentPortalJob': Unsatisfied dependency expressed
through field 'jobBuilderFactory'; nested exception is
org.springframework.beans.factory.UnsatisfiedDependencyException: Error
creating bean with name
'org.springframework.batch.core.configuration.annotation.
SimpleBatchConfiguration': Unsatisfied dependency expressed through field
'dataSource'; nested exception is
org.springframework.beans.factory.BeanCreationException:
Error creating bean
with name 'dataSource' defined in class path resource
[org/springframework/boot/autoconfigure/jdbc/
DataSourceConfiguration$Hikari.class]: Bean instantiation via factory method
failed; nested exception is
org.springframework.beans.BeanInstantiationException: Failed to instantiate
[com.zaxxer.hikari.HikariDataSource]: Factory method 'dataSource' threw
exception; nested exception is
org.springframework.boot.autoconfigure.jdbc.
DataSourceProperties$DataSourceBeanCreationException: Failed to determine a
suitable driver class

org.springframework.transaction.CannotCreateTransactionException: Could not open Hibernate Session for transaction

Error Logs:
Tests run: 1, Failures: 0, Errors: 1, Skipped: 0, Time elapsed: 2.372 sec <<< FAILURE!
testCRUDCategory(net.kzn.shoppingbackend.test.CategoryTestCase) Time elapsed: 0.124 sec <<< ERROR!
org.springframework.transaction.CannotCreateTransactionException: Could not open Hibernate Session for transaction; nested exception is org.hibernate.exception.GenericJDBCException: Unable to acquire JDBC Connection
at org.springframework.orm.hibernate5.HibernateTransactionManager.doBegin(HibernateTransactionManager.java:542)
at org.springframework.transaction.support.AbstractPlatformTransactionManager.getTransaction(AbstractPlatformTransactionManager.java:373)
at org.springframework.transaction.interceptor.TransactionAspectSupport.createTransactionIfNecessary(TransactionAspectSupport.java:447)
at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:277)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:96)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:213)
at com.sun.proxy.$Proxy32.add(Unknown Source)
HibernateConfig.java
#Configuration
#ComponentScan(basePackages={"net.kzn.shoppingbackend.dto"})
#EnableTransactionManagement
public class HibernateConfig {
// Change the below based on the DBMS you choose
private final static String DATABASE_URL = "jdbc:h2:tcp://localhost/~/onlineshopping";
private final static String DATABASE_DRIVER = "org.h2.Driver";
private final static String DATABASE_DIALECT = "org.hibernate.dialect.H2Dialect";
private final static String DATABASE_USERNAME = "sa";
private final static String DATABASE_PASSWORD = "";
// dataSource bean will be available
#Bean
public DataSource getDataSource() {
BasicDataSource dataSource = new BasicDataSource();
// Providing the database connection information
dataSource.setDriverClassName(DATABASE_DRIVER);
dataSource.setUrl(DATABASE_URL);
dataSource.setUsername(DATABASE_USERNAME);
dataSource.setPassword(DATABASE_PASSWORD);
return dataSource;
}
// sessionFactory bean will be available
#Bean
public SessionFactory getSessionFactory(DataSource dataSource) {
LocalSessionFactoryBuilder builder = new LocalSessionFactoryBuilder(dataSource);
builder.addProperties(getHibernateProperties());
builder.scanPackages("net.kzn.shoppingbackend.dto");
return builder.buildSessionFactory();
}
// All the hibernate properties will be returned in this method
private Properties getHibernateProperties() {
Properties properties = new Properties();
properties.put("hibernate.dialect", DATABASE_DIALECT);
properties.put("hibernate.show_sql", "true");
properties.put("hibernate.format_sql", "true");
return properties;
}
// transactionManager bean
#Bean
public HibernateTransactionManager getTransactionManager(SessionFactory sessionFactory) {
HibernateTransactionManager transactionManager = new HibernateTransactionManager(sessionFactory);
return transactionManager;
}
}
Test Class
CategoryTestCase.java
public class CategoryTestCase {
private static AnnotationConfigApplicationContext context;
private static CategoryDAO categoryDAO;
private Category category;
#BeforeClass
public static void init() {
context = new AnnotationConfigApplicationContext();
context.scan("net.kzn.shoppingbackend");
context.refresh();
categoryDAO = (CategoryDAO)context.getBean("categoryDAO");
}
#Test
public void testAddCategory() {
category = new Category();
category.setName("Laptop");
category.setDescription("This is some description for laptop!");
category.setImageURL("CAT_105.png");
assertEquals("Successfully added a category inside the table!",true,categoryDAO.add(category));
}
}
why I am getting Could not open Hibernate Session for transaction; nested exception , it seems everything is fine to why this error i am getting
YOu can check git Hub code too its same issue kindly help me to solve the issue
https://github.com/rustyamigo/online-shopping
I have cloned your project and found Connection is broken: "java.net.ConnectException: Connection refused: localhost" [90067-194]),You seem not to have started the H2 server. Based on your URL, you're using tcp connection, ie the server has to be started first.
I have some googling and found you can solve it by 2 ways:
you need a java master program which start the server like this:
org.h2.tools.Server.createTcpServer().start();
e.g:
in your test class-> ProductTestCase.java
#BeforeClass
public static void init() throws Exception {
org.h2.tools.Server.createTcpServer().start();
context = new AnnotationConfigApplicationContext();
context.scan("net.kzn.shoppingbackend");
context.refresh();
productDAO = (ProductDAO)context.getBean("productDAO");
}
or you could start it manually prior to your connection attempt like this:
java -cp h2*.jar org.h2.tools.Server

Spring boot not executing schema.sql script

I'm developing a Spring Boot web application and want to create a MySql database if it's not already created. So I've done a dump of my current database in order to have an empty schema of it. Put it in /src/main/resources, so maven brings it to /WEB-INF/classes when building the war file. That's how my application.properties is configured (according to Spring docs, that should create the DB from the script):
# DataSource settings: set here configurations for the database connection
spring.datasource.url = jdbc:mysql://localhost:3306/working_zones
spring.datasource.username = root
spring.datasource.password = password
spring.datasource.driverClassName = com.mysql.jdbc.Driver
# Specify the DBMS
spring.jpa.database = MYSQL
# Hibernate settings are prefixed with spring.jpa.hibernate.*
spring.jpa.hibernate.dialect = org.hibernate.dialect.MySQL5InnoDBDialect
And that's the error I get when I try to run the application (it complains about a non-existing DB):
2015-01-13 13:30:24.334 [main] ERROR o.s.boot.SpringApplication - Application startup failed
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private javax.sql.DataSource org.springframework.boot.autoconfigure.orm.jpa.JpaBaseConfiguration.dataSource; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'dataSource' defined in class path resource [org/springframework/boot/autoconfigure/jdbc/DataSourceAutoConfiguration$NonEmbeddedConfiguration.class]: Initialization of bean failed; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'dataSourceInitializer': Invocation of init method failed; nested exception is org.springframework.jdbc.datasource.init.UncategorizedScriptException: Failed to execute database script; nested exception is org.springframework.jdbc.CannotGetJdbcConnectionException: Could not get JDBC Connection; nested exception is com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Unknown database 'working_zones'
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:301) ~[spring-beans-4.0.8.RELEASE.jar:4.0.8.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1186) ~[spring-beans-4.0.8.RELEASE.jar:4.0.8.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:537) ~[spring-beans-4.0.8.RELEASE.jar:4.0.8.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:475) ~[spring-beans-4.0.8.RELEASE.jar:4.0.8.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:302) ~[spring-beans-4.0.8.RELEASE.jar:4.0.8.RELEASE]
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:228) ~[spring-beans-4.0.8.RELEASE.jar:4.0.8.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:298) ~[spring-beans-4.0.8.RELEASE.jar:4.0.8.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:193) ~[spring-beans-4.0.8.RELEASE.jar:4.0.8.RELEASE]
at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:370) ~[spring-beans-4.0.8.RELEASE.jar:4.0.8.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1095) ~[spring-beans-4.0.8.RELEASE.jar:4.0.8.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:990) ~[spring-beans-4.0.8.RELEASE.jar:4.0.8.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:504) ~[spring-beans-4.0.8.RELEASE.jar:4.0.8.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:475) ~[spring-beans-4.0.8.RELEASE.jar:4.0.8.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:302) ~[spring-beans-4.0.8.RELEASE.jar:4.0.8.RELEASE]
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:228) ~[spring-beans-4.0.8.RELEASE.jar:4.0.8.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:298) ~[spring-beans-4.0.8.RELEASE.jar:4.0.8.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:193) ~[spring-beans-4.0.8.RELEASE.jar:4.0.8.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:975) ~[spring-context-4.0.8.RELEASE.jar:4.0.8.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:752) ~[spring-context-4.0.8.RELEASE.jar:4.0.8.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:482) ~[spring-context-4.0.8.RELEASE.jar:4.0.8.RELEASE]
at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.refresh(EmbeddedWebApplicationContext.java:109) ~[spring-boot-1.1.9.RELEASE.jar:1.1.9.RELEASE]
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:691) [spring-boot-1.1.9.RELEASE.jar:1.1.9.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:320) [spring-boot-1.1.9.RELEASE.jar:1.1.9.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:952) [spring-boot-1.1.9.RELEASE.jar:1.1.9.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:941) [spring-boot-1.1.9.RELEASE.jar:1.1.9.RELEASE]
So it seems that Spring tries to connect to the database even schema.sql, which contains the script to create the DB, not executed. There are some related questions in Stack Overflow about that, but still can't get it working, even if I try with spring.datasource.initialize=true...
Well, looks like you can't do that from the common JDBC connect: creating a database in mysql from java
Hence Spring Boot can't do that for you automatically.
Please, don't mix the DB creating with its creation for its content: tables, procedures, triggers etc.
UPDATE
Yes, you can do that on the application startup. You just a separate initializer, which has an order before dataSourceInitializer.
A listerner on the application startup can resolve it. Following is the code.
public class DatabaseCreationListener implements ApplicationListener<ApplicationEnvironmentPreparedEvent> {
private AtomicBoolean received = new AtomicBoolean(false);
private ConfigurableEnvironment environment;
private Pattern JDBC_URL_PATTERN = Pattern.compile("jdbc:([a-zA-Z0-9_]+)://[0-9.:]+(?:/([a-zA-Z0-9_]+))?(\\?.*)?");
#Override
public void onApplicationEvent(ApplicationEnvironmentPreparedEvent event) {
// Think about twice invoking this listener
if (!received.compareAndSet(false, true)) {
return;
}
environment = event.getEnvironment();
// ConditionalOnClass
ClassLoader classLoader = event.getSpringApplication().getClassLoader();
if (!isPresent("org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType", classLoader)) {
return;
}
// DatabaseProperties
val databaseProperties = bind(DatabaseProperties.PREFIX, new DatabaseProperties());
if (!databaseProperties.shouldCreate()) {
return;
}
// DataSourceProperties
val dataSourceProperties = bind(databaseProperties.getDatasourceConfigPrefix(), new DataSourceProperties());
// Check for connection url
String url = dataSourceProperties.getUrl();
if (url == null) return;
Matcher matcher = JDBC_URL_PATTERN.matcher(url);
if (!matcher.matches()) return;
// Extract database provider and schema name from connection url
String databaseProvider = matcher.group(1);
String schemaName = matcher.group(2);
if (isBlank(schemaName)) return;
// Reset connection url
dataSourceProperties.setUrl(url.replace("/" + schemaName, ""));
// Build a new datasource and do create schema
DataSource dataSource = buildDataSource(dataSourceProperties);
try (Connection connection = DataSourceUtils.getConnection(dataSource)) {
connection.createStatement().execute(createSchemaIfAbsent(databaseProvider, schemaName));
} catch (SQLException ignored) {
}
}
private <T> T bind(String prefix, T t) {
RelaxedDataBinder binder = new RelaxedDataBinder(t, prefix);
binder.bind(new PropertySourcesPropertyValues(environment.getPropertySources()));
return t;
}
private static DataSource buildDataSource(DataSourceProperties dataSourceProperties) {
String url = dataSourceProperties.getUrl();
String username = dataSourceProperties.getUsername();
String password = dataSourceProperties.getPassword();
return new SingleConnectionDataSource(url, username, password, false);
}
private static String createSchemaIfAbsent(String databaseProvider, String schemaName) {
DatabaseDialects dialects = DatabaseDialects.getDatabaseDialect(databaseProvider);
if (dialects == null) {
throw new IllegalArgumentException("Unknown schema:" + schemaName);
}
switch (dialects) {
case MYSQL:
return "CREATE DATABASE IF NOT EXISTS " + schemaName;
default:
throw new UnsupportedOperationException("Unsupported schema:" + dialects);
}
}
}
And Following is the DatabaseProperties.
#Data
#ConfigurationProperties(prefix = DatabaseProperties.PREFIX)
public class DatabaseProperties {
public final static String PREFIX = "spring.database";
private boolean autoCreate;
private String datasourceConfigPrefix = "spring.datasource";
public boolean shouldCreate() {
return isAutoCreate() && isNotBlank(getDatasourceConfigPrefix());
}
}
The listener should be actived by config in META-INF/spring.factories.
org.springframework.context.ApplicationListener=\
yourpackage.DatabaseCreationListener
If you want config syntax hint in an underlying IDE, add the optional depenedncy spring-boot-configuration-processor and file META-INF/additional-spring-configuration-metadata.json.
{
"groups": [
{
"sourceType": "yourpackage.DatabaseProperties",
"name": "spring.database",
"type": "yourpackage.DatabaseProperties"
}
],
"properties": [
{
"sourceType": "yourpackage.DatabaseProperties",
"defaultValue": false,
"name": "auto-create",
"type": "java.lang.Boolean"
},
{
"sourceType": "youpackage.DatabaseProperties",
"defaultValue": "spring.datasource",
"name": "datasource-config-prefix",
"type": "java.lang.String"
}
]
}
As mentioned in this github post, you can add:
spring.datasource.url=jdbc:mysql://localhost:3309/course_api_db?createDatabaseIfNotExist=true
To execute the schema.sql

Categories