Spring batch with DB2 and MongoDB using Spring boot - mongodb

I need to read the DB2 database and copy data to mongoDB using Spring Batch. As I am going to write the data to mongoDB, so I dont need the transaction. I would like to keep the metadata tables scripts in mongoDB only not in DB2 but I couldn't find the metadata tables scripts for mongoDB. In the server startup time, spring boot expect the batch_job_instance table in Db2 instead of mongoDB. I annotated mongoDB as primary but still it is throwing an error.
Someone can help me with this. Thanks in advance.
MongoConfig.java:
#Configuration
#EnableMongoRepositories("com.test.mongodb")
public class MongoConfig extends AbstractMongoConfiguration {
private final Logger log = LoggerFactory.getLogger(MongoConfig.class);
#Value("${spring.data.mongodb.host}")
private String host;
#Value("${spring.data.mongodb.port}")
private Integer port;
#Value("${spring.data.mongodb.username}")
private String username;
#Value("${spring.data.mongodb.database}")
private String database;
#Value("${spring.data.mongodb.password}")
private String password;
#Bean
public ValidatingMongoEventListener validatingMongoEventListener() {
return new ValidatingMongoEventListener(validator());
}
#Bean
public LocalValidatorFactoryBean validator() {
return new LocalValidatorFactoryBean();
}
#Override
public String getDatabaseName() {
return database;
}
#Override
#Bean
public Mongo mongo() throws Exception {
return new MongoClient(singletonList(new ServerAddress(host, port)),
singletonList(MongoCredential.createCredential(username, database, password.toCharArray())));
}
#Override
#Bean
#Primary
#ConfigurationProperties(prefix = "spring.data.mongodb")
public MongoTemplate mongoTemplate() throws Exception {
return new MongoTemplate(mongo(), database);
}
}
application.properties:
# DB2
spring.datasource.jndi-name=java:jboss/datasources/Db2XaDsn
# Mongo DB
spring.data.mongodb.host=localhost
spring.data.mongodb.port=27017
spring.data.mongodb.username=admin
spring.data.mongodb.password=admin
spring.data.mongodb.database=test
Batch class:
#Configuration
#EnableBatchProcessing
public class ItemBatch {
#Autowired
private JobBuilderFactory jobBuilderFactory;
#Autowired
private StepBuilderFactory stepBuilderFactory;
#Autowired
EntityManagerFactory entityManagerFactory;
#Autowired
MongoTemplate mongoTemplate;
#Bean
public Job readDB2() {
return jobBuilderFactory.get("readDB2").start(step1()).build();
}
#Bean
public Step step1() {
return stepBuilderFactory.get("step1").<com.model.db2.Item, Item>chunk(200).reader(reader())
.writer(writer()).build();
}
#Bean
public ItemReader<com.model.db2.Item> reader() {
JpaPagingItemReader<com.model.db2.Item> reader = new JpaPagingItemReader<>();
reader.setQueryString("select i from Item i");
reader.setEntityManagerFactory(entityManagerFactory);
return reader;
}
#Bean
public MongoItemWriter<Item> writer() {
MongoItemWriter<Item> writer = new MongoItemWriter<>();
try {
writer.setTemplate(mongoTemplate);
} catch (Exception e) {
e.printStackTrace();
}
writer.setCollection("item");
return writer;
}
}
Error:
00:44:39,484 ERROR [org.jboss.msc.service.fail] (ServerService Thread Pool -- 72) MSC000001: Failed to start service jboss.undertow.deployment.default-server.default-host./itemapi: org.jboss.msc.service.StartException in service jboss.undertow.deployment.default-server.default-host./itemapi: java.lang.RuntimeException: java.lang.IllegalStateException: Failed to execute CommandLineRunner
at org.wildfly.extension.undertow.deployment.UndertowDeploymentService$1.run(UndertowDeploymentService.java:85)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)
at org.jboss.threads.JBossThread.run(JBossThread.java:320)
Caused by: java.lang.RuntimeException: java.lang.IllegalStateException: Failed to execute CommandLineRunner
at io.undertow.servlet.core.DeploymentManagerImpl.deploy(DeploymentManagerImpl.java:231)
at org.wildfly.extension.undertow.deployment.UndertowDeploymentService.startContext(UndertowDeploymentService.java:100)
at org.wildfly.extension.undertow.deployment.UndertowDeploymentService$1.run(UndertowDeploymentService.java:82)
... 6 more
Caused by: java.lang.IllegalStateException: Failed to execute CommandLineRunner
at org.springframework.boot.SpringApplication.callRunner(SpringApplication.java:735)
at org.springframework.boot.SpringApplication.callRunners(SpringApplication.java:716)
at org.springframework.boot.SpringApplication.afterRefresh(SpringApplication.java:703)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:304)
at org.springframework.boot.web.support.SpringBootServletInitializer.run(SpringBootServletInitializer.java:154)
at org.springframework.boot.web.support.SpringBootServletInitializer.createRootApplicationContext(SpringBootServletInitializer.java:134)
at org.springframework.boot.web.support.SpringBootServletInitializer.onStartup(SpringBootServletInitializer.java:87)
at org.springframework.web.SpringServletContainerInitializer.onStartup(SpringServletContainerInitializer.java:169)
at io.undertow.servlet.core.DeploymentManagerImpl.deploy(DeploymentManagerImpl.java:184)
... 8 more
Caused by: org.springframework.jdbc.BadSqlGrammarException: PreparedStatementCallback; bad SQL grammar [SELECT JOB_INSTANCE_ID, JOB_NAME from BATCH_JOB_INSTANCE where JOB_NAME = ? order by JOB_INSTANCE_ID desc]; nested exception is com.ibm.db2.jcc.am.SqlSyntaxErrorException: DB2 SQL Error: SQLCODE=-204, SQLSTATE=42704, SQLERRMC=TEST.BATCH_JOB_INSTANCE, DRIVER=4.18.60
at org.springframework.jdbc.support.SQLErrorCodeSQLExceptionTranslator.doTranslate(SQLErrorCodeSQLExceptionTranslator.java:231)
at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:73)
at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:649)
at org.springframework.jdbc.core.JdbcTemplate.query(JdbcTemplate.java:684)
at org.springframework.jdbc.core.JdbcTemplate.query(JdbcTemplate.java:716)
at org.springframework.jdbc.core.JdbcTemplate.query(JdbcTemplate.java:726)
at org.springframework.batch.core.repository.dao.JdbcJobInstanceDao.getJobInstances(JdbcJobInstanceDao.java:230)
at org.springframework.batch.core.explore.support.SimpleJobExplorer.getJobInstances(SimpleJobExplorer.java:173)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:333)
at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:190)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157)
at org.springframework.batch.core.configuration.annotation.SimpleBatchConfiguration$PassthruAdvice.invoke(SimpleBatchConfiguration.java:127)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:213)
at com.sun.proxy.$Proxy302.getJobInstances(Unknown Source)
at org.springframework.boot.autoconfigure.batch.JobLauncherCommandLineRunner.getNextJobParameters(JobLauncherCommandLineRunner.java:131)
at org.springframework.boot.autoconfigure.batch.JobLauncherCommandLineRunner.execute(JobLauncherCommandLineRunner.java:212)
at org.springframework.boot.autoconfigure.batch.JobLauncherCommandLineRunner.executeLocalJobs(JobLauncherCommandLineRunner.java:231)
at org.springframework.boot.autoconfigure.batch.JobLauncherCommandLineRunner.launchJobFromProperties(JobLauncherCommandLineRunner.java:123)
at org.springframework.boot.autoconfigure.batch.JobLauncherCommandLineRunner.run(JobLauncherCommandLineRunner.java:117)
at org.springframework.boot.SpringApplication.callRunner(SpringApplication.java:732)
... 16 more
Caused by: com.ibm.db2.jcc.am.SqlSyntaxErrorException: DB2 SQL Error: SQLCODE=-204, SQLSTATE=42704, SQLERRMC=TEST.BATCH_JOB_INSTANCE, DRIVER=4.18.60
at com.ibm.db2.jcc.am.kd.a(kd.java:747)
at com.ibm.db2.jcc.am.kd.a(kd.java:66)
at com.ibm.db2.jcc.am.kd.a(kd.java:135)
at com.ibm.db2.jcc.am.bp.c(bp.java:2788)
at com.ibm.db2.jcc.am.bp.d(bp.java:2776)
at com.ibm.db2.jcc.am.bp.a(bp.java:2209)
at com.ibm.db2.jcc.am.cp.a(cp.java:7886)
at com.ibm.db2.jcc.t4.bb.h(bb.java:141)
at com.ibm.db2.jcc.t4.bb.b(bb.java:41)
at com.ibm.db2.jcc.t4.p.a(p.java:32)
at com.ibm.db2.jcc.t4.vb.i(vb.java:145)
at com.ibm.db2.jcc.am.bp.kb(bp.java:2178)
at com.ibm.db2.jcc.am.cp.xc(cp.java:3686)
at com.ibm.db2.jcc.am.cp.b(cp.java:4493)
at com.ibm.db2.jcc.am.cp.kc(cp.java:767)
at com.ibm.db2.jcc.am.cp.executeQuery(cp.java:732)
at org.jboss.jca.adapters.jdbc.WrappedPreparedStatement.executeQuery(WrappedPreparedStatement.java:504)
at org.springframework.jdbc.core.JdbcTemplate$1.doInPreparedStatement(JdbcTemplate.java:692)
at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:633)
... 38 more

Answering my own question. I am able use spring batch without metadata tables using the below configuration:
#Configuration
public class SpringBatchInMemoryConfiguration {
#Bean
public ResourcelessTransactionManager transactionManager() {
return new ResourcelessTransactionManager();
}
#Bean
public MapJobRepositoryFactoryBean mapJobRepositoryFactory(ResourcelessTransactionManager txManager)
throws Exception {
MapJobRepositoryFactoryBean factory = new MapJobRepositoryFactoryBean(txManager);
factory.afterPropertiesSet();
return factory;
}
#Bean
public JobRepository jobRepository(MapJobRepositoryFactoryBean factory) throws Exception {
return factory.getObject();
}
#Bean
public JobExplorer jobExplorer(MapJobRepositoryFactoryBean factory) {
return new SimpleJobExplorer(factory.getJobInstanceDao(), factory.getJobExecutionDao(),
factory.getStepExecutionDao(), factory.getExecutionContextDao());
}
#Bean
public SimpleJobLauncher jobLauncher(JobRepository jobRepository) throws Exception {
SimpleJobLauncher launcher = new SimpleJobLauncher();
launcher.setJobRepository(jobRepository);
launcher.afterPropertiesSet();
return launcher;
}
}

Related

javax.persistence.TransactionRequiredException: Executing an update/delete query : Spring boot Migration from 1.5.4 to 2.7.5

I am migrating the spring boot app from spring boot 1.5.4 to spring boot 2.7.5, In old code I have hibernate at DAO layer. (does the migration caused the issue, I did not find very particular about the issue )
properties file has connection details and used below key
spring.jpa.properties.hibernate.current_session_context_class=org.springframework.orm.hibernate5.SpringSessionContext
Application class have following annotations,
#EnableTransactionManagement #EnableJpaRepositories(basePackages = {"repository package"}) #ComponentScan(basePackages = {"base package"}) #EntityScan(basePackages = {"entity package"})
DAO code :
private EntityManager entityManager;
private Session getSession() {
return entityManager.unwrap(Session.class);
}
// problematic code
public void doSomething(){
String hqlBuilder = "Update Query statement"
Query query = getSession().createQuery(hqlBuilder);
int result = query.executeUpdate();
}```
Service code:
Service class has #Transctional defined at class level however it throws exception on invoking the doSomething() method on DAO instance
`**Caused by: javax.persistence.TransactionRequiredException: Executing an update/delete query**
at org.hibernate.internal.AbstractSharedSessionContract.checkTransactionNeededForUpdateOperation(AbstractSharedSessionContract.java:445)
at org.hibernate.query.internal.AbstractProducedQuery.executeUpdate(AbstractProducedQuery.java:1692)
at <removed the package path>.dao.impl.LastViewedHistoryElementDaoHibernate.insertOrUpdate(LastViewedHistoryElementDaoHibernate.java:122)
at impl.LastViewedHistoryElementDaoHibernate$$FastClassBySpringCGLIB$$f8fba493.invoke(<generated>)
at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:218)
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:793)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163)
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:763)
at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:137)
... 271 common frames omitted`
**In DAO method returns it throws the TransactionRequiredException : No Transaction in progress**
Thank you, I did applied the #EnableTransactionManagement #Transactional, added spring jpa. I did configure Transaction manager in config also however not luck,
```#Autowired
HikariDataSource dataSource;
#Bean
public LocalSessionFactoryBean sessionFactory() {
LocalSessionFactoryBean sessionFactory = new LocalSessionFactoryBean();
sessionFactory.setDataSource(dataSource);
sessionFactory.setPackagesToScan(
new String[]{"<My packages>"});
//sessionFactory.setHibernateProperties(hibernateProperties());
return sessionFactory;
}
#Bean
public PlatformTransactionManager transactionManager() {
HibernateTransactionManager hibernateTransactionManager
= new HibernateTransactionManager();
hibernateTransactionManager.setSessionFactory(sessionFactory().getObject());
return hibernateTransactionManager;
}```
but still same error as Caused by: javax.persistence.TransactionRequiredException: no transaction is in progress
at org.hibernate.internal.AbstractSharedSessionContract.checkTransactionNeededForUpdateOperation(AbstractSharedSessionContract.java:445)
at org.hibernate.internal.SessionImpl.checkTransactionNeededForUpdateOperation(SessionImpl.java:3496)
at org.hibernate.internal.SessionImpl.doFlush(SessionImpl.java:1399)
at org.hibernate.internal.SessionImpl.flush(SessionImpl.java:1394)
at org.springframework.orm.hibernate5.SessionFactoryUtils.flush(SessionFactoryUtils.java:113)
at org.springframework.orm.hibernate5.SpringSessionSynchronization.beforeCommit(SpringSessionSynchronization.java:95)
at org.springframework.transaction.support.TransactionSynchronizationUtils.triggerBeforeCommit(TransactionSynchronizationUtils.java:97)
at org.springframework.transaction.support.AbstractPlatformTransactionManager.triggerBeforeCommit(AbstractPlatformTransactionManager.java:916)
at org.springframework.transaction.support.AbstractPlatformTransactionManager.processCommit(AbstractPlatformTransactionManager.java:727)
at org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:711)
at org.springframework.transaction.interceptor.TransactionAspectSupport.commitTransactionAfterReturning(TransactionAspectSupport.java:654)
at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:407)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:119)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:763)
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:708)

Spring-batch exception: org.springframework.batch.core.launch.NoSuchJobException: No job configuration with the name [] was registered

I am seeing this exception when stopping a running job using jobOperator.stop(id) or when I want to restart it using jobOperator.restart(id).
I don't have any idea why the MapJobRegistry is empty ... Am I missing a step ?
I have reproduced the problem using the complete example from https://github.com/spring-guides/gs-batch-processing.git
#Configuration
#EnableBatchProcessing
public class BatchConfiguration {
#Autowired
public JobBuilderFactory jobBuilderFactory;
#Autowired
public StepBuilderFactory stepBuilderFactory;
// end::setup[]
#Autowired
JobRepository jobRepository;
// tag::readerwriterprocessor[]
#Bean
public FlatFileItemReader<Person> reader() {
return new FlatFileItemReaderBuilder<Person>()
.name("personItemReader")
.resource(new ClassPathResource("sample-data.csv"))
.delimited()
.names(new String[]{"firstName", "lastName"})
.fieldSetMapper(new BeanWrapperFieldSetMapper<Person>() {{
setTargetType(Person.class);
}})
.build();
}
#Bean
public PersonItemProcessor processor() {
return new PersonItemProcessor();
}
#Bean
public JdbcBatchItemWriter<Person> writer(DataSource dataSource) {
return new JdbcBatchItemWriterBuilder<Person>()
.itemSqlParameterSourceProvider(new BeanPropertyItemSqlParameterSourceProvider<>())
.sql("INSERT INTO people (first_name, last_name) VALUES (:firstName, :lastName)")
.dataSource(dataSource)
.build();
}
// end::readerwriterprocessor[]
// tag::jobstep[]
#Bean
public Job importUserJob(JobCompletionNotificationListener listener, Step step1) {
return jobBuilderFactory.get("importUserJob")
.incrementer(new RunIdIncrementer())
.listener(listener)
.flow(step1)
.end()
.build();
}
#Bean
public Step step1(JdbcBatchItemWriter<Person> writer) {
return stepBuilderFactory.get("step1")
.<Person, Person> chunk(10)
.reader(reader())
.processor(processor())
.writer(writer)
.build();
}
// end::jobstep[]
#Bean
public JobLauncher simpleJobLauncher() throws Exception {
SimpleJobLauncher jobLauncher = new SimpleJobLauncher();
jobLauncher.setJobRepository(jobRepository);
jobLauncher.setTaskExecutor(new SimpleAsyncTaskExecutor());
jobLauncher.afterPropertiesSet();
return jobLauncher;
}
}
The rest controller
#RestController
public class BatchController {
Logger logger = LoggerFactory.getLogger(BatchController.class);
#Autowired
JobLauncher simpleJobLauncher;
#Autowired
Job importUserJob;
#Autowired
JobOperator jobOperator;
#RequestMapping("/startNewJob")
public String handle() {
try {
JobParameters jobParameters = new JobParametersBuilder().addLong("time", System.currentTimeMillis())
.toJobParameters();
JobExecution jobExecution = simpleJobLauncher.run(importUserJob, jobParameters);
return jobExecution.toString();
} catch (Exception e) {
logger.info(e.getMessage());
return ("An error has occured, please check the logs");
}
}
#RequestMapping("/stopJob/{id}")
public Boolean stopJob(#PathVariable Long id) throws Exception {
logger.info("stopJob "+id);
return jobOperator.stop(id);
}
#RequestMapping("/restartJob/{id}")
public Long restartJob(#PathVariable Long id) throws Exception {
logger.info("restartJob "+id);
return jobOperator.restart(id);
}
}
Stacktrace while restarting the job
2020-11-12 21:47:16.452 ERROR 26252 --- [nio-8080-exec-3] o.a.c.c.C.[.[.[/].[dispatcherServlet] : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.springframework.batch.core.launch.NoSuchJobException: No job configuration with the name [importUserJob] was registered] with root cause
org.springframework.batch.core.launch.NoSuchJobException: No job configuration with the name [importUserJob] was registered
at org.springframework.batch.core.configuration.support.MapJobRegistry.getJob(MapJobRegistry.java:68) ~[spring-batch-core-4.2.1.RELEASE.jar:4.2.1.RELEASE]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_92]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_92]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_92]
at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_92]
at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:344) ~[spring-aop-5.2.2.RELEASE.jar:5.2.2.RELEASE]
at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:198) ~[spring-aop-5.2.2.RELEASE.jar:5.2.2.RELEASE]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163) ~[spring-aop-5.2.2.RELEASE.jar:5.2.2.RELEASE]
at org.springframework.batch.core.configuration.annotation.SimpleBatchConfiguration$PassthruAdvice.invoke(SimpleBatchConfiguration.java:127) ~[spring-batch-core-4.2.1.RELEASE.jar:4.2.1.RELEASE]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) ~[spring-aop-5.2.2.RELEASE.jar:5.2.2.RELEASE]
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:212) ~[spring-aop-5.2.2.RELEASE.jar:5.2.2.RELEASE]
at com.sun.proxy.$Proxy68.getJob(Unknown Source) ~[na:na]
at org.springframework.batch.core.launch.support.SimpleJobOperator.restart(SimpleJobOperator.java:275) ~[spring-batch-core-4.2.1.RELEASE.jar:4.2.1.RELEASE]
at org.springframework.batch.core.launch.support.SimpleJobOperator$$FastClassBySpringCGLIB$$44ee6049.invoke() ~[spring-batch-core-4.2.1.RELEASE.jar:4.2.1.RELEASE]
at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:218) ~[spring-core-5.2.2.RELEASE.jar:5.2.2.RELEASE]
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:685) ~[spring-aop-5.2.2.RELEASE.jar:5.2.2.RELEASE]
at org.springframework.batch.core.launch.support.SimpleJobOperator$$EnhancerBySpringCGLIB$$853e8727.restart() ~[spring-batch-core-4.2.1.RELEASE.jar:4.2.1.RELEASE]
at com.example.batchprocessing.BatchController.restartJob(BatchController.java:60) ~[classes/:na]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_92]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_92]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_92]
at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_92]
at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:190) ~[spring-web-5.2.2.RELEASE.jar:5.2.2.RELEASE]
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:138) ~[spring-web-5.2.2.RELEASE.jar:5.2.2.RELEASE]
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:106) ~[spring-webmvc-5.2.2.RELEASE.jar:5.2.2.RELEASE]
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:888) ~[spring-webmvc-5.2.2.RELEASE.jar:5.2.2.RELEASE]
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:793) ~[spring-webmvc-5.2.2.RELEASE.jar:5.2.2.RELEASE]
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87) ~[spring-webmvc-5.2.2.RELEASE.jar:5.2.2.RELEASE]
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1040) ~[spring-webmvc-5.2.2.RELEASE.jar:5.2.2.RELEASE]
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:943) ~[spring-webmvc-5.2.2.RELEASE.jar:5.2.2.RELEASE]
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006) ~[spring-webmvc-5.2.2.RELEASE.jar:5.2.2.RELEASE]
at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:898) ~[spring-webmvc-5.2.2.RELEASE.jar:5.2.2.RELEASE]
The JobOperator requires a JobLocator to locate jobs to restart, stop, etc. This JobLocator (typically a MapJobRegistry) should be populated with known jobs, and this should be done either manually or by adding a JobRegistryBeanPostProcessor to the application context.
This is explained in the reference documentation here: JobRegistry.
I simply added a JobRegistryBeanPostProcessor and set it the jobRegistry.
#Autowired
JobRegistry jobRegistry;
#Bean
public JobRegistryBeanPostProcessor jobRegistryBeanPostProcessor() {
JobRegistryBeanPostProcessor postProcessor = new JobRegistryBeanPostProcessor();
postProcessor.setJobRegistry(jobRegistry);
return postProcessor;
}
You can also trigger job using jobLauncher. Here is a blog explaining it.
In short you can refer to this code.
#Component
public class JobScheduler
{
#Autowired
JobLauncher jobLauncher;
#Qualifier("jobBeanName") // if you have multiple jobs
#Autowired
Job job;
#Scheduled(cron = "* * * * * *")
public void runJob() {
jobLauncher.run(job, new JobParameters());
}
}

Trying to use Spring with JPA and JTA with only Spring Annotation

I am setting up an application that accept a REST call and then does some DB work. I am trying to use Spring to do everything via annotations, except I would like to keep the persistence.xml file. However, I am being thrown an error that there is not a Bean called the unitName I have added to the #PersistenceContext.
#Repository
#Transactional
public class UserController implements Serializable {
private static final long serialVersionUID = 4625223295588959802L;
#PersistenceContext(unitName="PerfJPASpring")
private EntityManager em;
#Transactional
public void addUser(User user) {
em.persist(user);
}
#Transactional
public void deleteAll() {
em.createNamedQuery("User.deleteAll").executeUpdate();
}
#Transactional
public List<User> selectAllRecords() {
return em.createNamedQuery("User.findAll").getResultList();
}
}
The other issue I have is how do I get Spring to use the persistence.xml and not define the DataSource in the LocalContainerEntityManagerFactoryBean. I have added the Datasource to the App Server.
#Configuration
#EnableTransactionManagement
#EnableJpaRepositories(basePackageClasses=UserController.class)
public class DatabaseConfig {
#Bean
public LocalContainerEntityManagerFactoryBean entityManagerFactory() {
EclipseLinkJpaVendorAdapter vendorAdapter = new EclipseLinkJpaVendorAdapter();
vendorAdapter.setGenerateDdl(true);
vendorAdapter.setShowSql(false);
LocalContainerEntityManagerFactoryBean factory = new LocalContainerEntityManagerFactoryBean();
factory.setJpaVendorAdapter(vendorAdapter);
factory.setPackagesToScan("com.example.jpa.model");
factory.setDataSource(dataSource());
Properties jpaProps = new Properties();
jpaProps.put("eclipselink.weaving", "false");
factory.setJpaProperties(jpaProps);
return factory;
}
#Bean
public JpaTransactionManager transactionManager() throws SQLException {
JpaTransactionManager txManager = new JpaTransactionManager();
txManager.setEntityManagerFactory(entityManagerFactory().getObject());
return txManager;
}
public DataSource dataSource() {
try {
Context initCtx = new InitialContext();
return (DataSource) initCtx.lookup("jdbc/userdb");
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException("Unable to lookup datasource", e);
}
}
}
The unitName does match that in the persistence.xml file.
<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.1" xmlns="http://xmlns.jcp.org/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd">
<persistence-unit name="PerfJPASpring" transaction-type="JTA">
<provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
<jta-data-source>jdbc/userdb</jta-data-source>
<class>com.example.jpa.model.User</class>
</persistence-unit>
</persistence>
And this is the error I am receiving.
Uncaught init() exception created by servlet [DispatcherServlet] in application [PerfJPASpring]: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'userController': Injection of persistence dependencies failed; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'PerfJPASpring' is defined
at org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor.postProcessPropertyValues(PersistenceAnnotationBeanPostProcessor.java:357)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1219)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:543)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:482)
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:751)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:839)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:538)
at org.springframework.web.servlet.FrameworkServlet.configureAndRefreshWebApplicationContext(FrameworkServlet.java:668)
at org.springframework.web.servlet.FrameworkServlet.initWebApplicationContext(FrameworkServlet.java:540)
at org.springframework.web.servlet.FrameworkServlet.initServletBean(FrameworkServlet.java:494)
at org.springframework.web.servlet.HttpServletBean.init(HttpServletBean.java:136)
at javax.servlet.GenericServlet.init(GenericServlet.java:244)
at [internal classes]
Could point me in the right direction for Spring to use the unitName and how I can avoid specifying the datasource in the Db Config?
Thanks.
I found the issue. First, since I am using JTA, then I can remove #Transactional and remove the Datasource and replace it with the setPersistenceUnitName. Now it uses the persistence.xml file and JTA.
The Service:
#Repository
public class UserController implements Serializable {
private static final long serialVersionUID = 4625223295588959802L;
#PersistenceContext(unitName="PerfJPASpring")
private EntityManager em;
public void addUser(User user) {
em.persist(user);
}
public void deleteAll() {
em.createNamedQuery("User.deleteAll").executeUpdate();
}
public List<User> selectAllRecords() {
return em.createNamedQuery("User.findAll").getResultList();
}
}
Database Config:
#Configuration
#EnableJpaRepositories(basePackageClasses=UserController.class)
public class DatabaseConfig {
#Bean
public LocalContainerEntityManagerFactoryBean entityManagerFactory() {
EclipseLinkJpaVendorAdapter vendorAdapter = new EclipseLinkJpaVendorAdapter();
vendorAdapter.setGenerateDdl(true);
vendorAdapter.setShowSql(false);
LocalContainerEntityManagerFactoryBean factory = new LocalContainerEntityManagerFactoryBean();
factory.setJpaVendorAdapter(vendorAdapter);
factory.setPackagesToScan("com.example.jpa.model");
factory.setPersistenceUnitName("PerfJPASpring");
Properties jpaProps = new Properties();
jpaProps.put("eclipselink.weaving", "false");
factory.setJpaProperties(jpaProps);
return factory;
}
#Bean
public JpaTransactionManager transactionManager() throws SQLException {
JpaTransactionManager txManager = new JpaTransactionManager();
txManager.setEntityManagerFactory(entityManagerFactory().getObject());
return txManager;
}
}

CONCURRENT_MAP_PUT failed at Address 192.168.11.208

I am trying to store data synchronously in cache and mongoDB. I am getting this exception
Exception in thread "main" com.hazelcast.core.HazelcastException: CONCURRENT_MAP_PUT failed at Address[192.168.11.208]:5702 because of an exception thrown at Address[192.168.11.208]:5701
at com.hazelcast.impl.BaseManager.rethrowException(BaseManager.java:188)
at com.hazelcast.impl.ConcurrentMapManager$MPut.txnalPut(ConcurrentMapManager.java:1902)
at com.hazelcast.impl.ConcurrentMapManager$MPut.txnalPut(ConcurrentMapManager.java:1818)
at com.hazelcast.impl.ConcurrentMapManager$MPut.put(ConcurrentMapManager.java:1682)
at com.hazelcast.impl.MProxyImpl$MProxyReal.put(MProxyImpl.java:632)
at com.hazelcast.impl.MProxyImpl$MProxyReal.put(MProxyImpl.java:606)
at com.hazelcast.impl.MProxyImpl.put(MProxyImpl.java:173)
at com.hazelcast.impl.MProxyImpl.put(MProxyImpl.java:124)
at mypackage.dao.EmployeeDAO.createNewEmployee(EmployeeDAO.java:52)
at mypackage.services.EmployeeManager.createNewEmployee(EmployeeManager.java:25)
at mypackage.controllers.EmployeeController.createNewEmployee(EmployeeController.java:24)
at mypackage.hazelcastspring.App.main(App.java:29)
Caused by: java.lang.NullPointerException
at mypackage.services.EmployeeMapstore.store(EmployeeMapstore.java:61)
at mypackage.services.EmployeeMapstore.store(EmployeeMapstore.java:1)
at com.hazelcast.impl.concurrentmap.MapStoreWrapper.store(MapStoreWrapper.java:114)
at com.hazelcast.impl.ConcurrentMapManager$PutOperationHandler$PutStorer.doMapStoreOperation(ConcurrentMapManager.java:3091)
at com.hazelcast.impl.ConcurrentMapManager$AbstractMapStoreOperation.run(ConcurrentMapManager.java:3795)
at com.hazelcast.impl.executor.ParallelExecutorService$ParallelExecutorImpl$ExecutionSegment.run(ParallelExecutorService.java:212)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)
at com.hazelcast.impl.ExecutorThreadFactory$1.run(ExecutorThreadFactory.java:38
I am having POJO class contains two String and i am using com.hazlecast.core.Mapstore library
Mainclass
public static void main(String[] args) {
CacheTesting testObj = new CacheTesting();
ApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
EmployeeController obj = (EmployeeController) context.getBean("employeeController");
obj.createNewEmployee();
testObj.cacheMembers();
testObj.clearCacheMembers();
testObj.cacheSize();
testObj.deleteCache(2);
testObj.getCacheMember(1);}
/////Dao class
public EmployeeDTO createNewEmployee() {
System.out.println("----Create new employee of DAO class called----");
getEmployeeDTO.setFirstName("Name");
getEmployeeDTO.setLastName("lastName");
System.out.println("DAO object: "+getEmployeeDTO);
getEmployeeMap().put(3,getEmployeeDTO);
return getEmployeeDTO;
}
////MapStore class
public class EmployeeMapstore implements MapStore<Integer, EmployeeDTO> {
#Autowired
EmployeeDTO getEmployeeDTO;
#Autowired
MongoOperations mongoOperations;
public synchronized void store(Integer key, EmployeeDTO geEmployeeDTO) {
System.out.println("----Store method of mapstore called----");
System.out.println("Before put method/Store method object: "+getEmployeeDTO);
mongoOperations.save(getEmployeeDTO);

Spring batch use JpaPagingItemReader JpaItemWriter no transaction is in progress

My project uses java config, the DataSource entityManagerFactory PlatformTransactionManager created by other java config file.
When ItemReader read data, ItemProcessor data transformed ItemWriter has some error
How can I solve this problem?
Error message
2015-01-17 16:26:30.390 ERROR AbstractStep:225 - Encountered an error executing step testStep in job validJob
javax.persistence.TransactionRequiredException: no transaction is in progress
at org.hibernate.jpa.spi.AbstractEntityManagerImpl.checkTransactionNeeded(AbstractEntityManagerImpl.java:1171)
at org.hibernate.jpa.spi.AbstractEntityManagerImpl.flush(AbstractEntityManagerImpl.java:1332)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:483)
How can I enable transactions on the following Code:
#Configuration
#EnableBatchProcessing
public class JobConfiguration {
#Inject
private PlatformTransactionManager transactionManager;
#Inject
private EntityManagerFactory emf;
#Bean
public Job validJob(JobBuilderFactory jobBuilderFactory,Step step) {
return jobBuilderFactory.get("validJob").flow(step).end().build();
}
#Bean
public Step testStep(StepBuilderFactory stepBuilderFactory, ItemReader<PurchaseOrder> reader,
ItemWriter<PurchaseOrder> writer, ItemProcessor<PurchaseOrder, PurchaseOrder> processor) {
return stepBuilderFactory.get("testStep")//
.transactionManager(transactionManager)//
.<PurchaseOrder, PurchaseOrder>chunk(100)//
.reader(reader)//
.processor(processor)//
.writer(writer)//
.build();
}
#Bean
public ItemReader<PurchaseOrder> reader() {
JpaPagingItemReader<PurchaseOrder> reader = new JpaPagingItemReader<PurchaseOrder>();
reader.setEntityManagerFactory(emf);
reader.setQueryString(" select p from PurchaseOrder p ");
reader.setTransacted(false);
return reader;
}
#Bean
public ItemProcessor<PurchaseOrder, PurchaseOrder> processor() {
return new PurchaseOrderItemProcessor();
}
#Bean
public ItemWriter<PurchaseOrder> writer() {
JpaItemWriter<PurchaseOrder> writer = new JpaItemWriter<PurchaseOrder>();
writer.setEntityManagerFactory(emf);
return writer;
}