I tried to use Multithreaded for my step like below, but got an exception below:
My step:
Code:
<step id="generateRecordFile" >
<tasklet>
<chunk reader="inputFileReader" writer="outputFileWriter"
commit-interval="100" task-executor="asyncTaskExecutor">
<streams>
<stream ref="inputFileReader" />
</streams>
</chunk>
</tasklet>
</step>
<beans:bean id="asyncTaskExecutor"
class="org.springframework.core.task.SimpleAsyncTaskExecutor" />
Reader:
<bean id="inputFileReader"
class="org.springframework.batch.item.file.MultiResourceItemReader"
scope="step">
<property name="resources" value="#{jobParameters['fileLocation']}" />
<property name="delegate" ref="fileInputFileReader" />
</bean>
<bean id="fileProductFeeReader" class="<package>.SynchronizedItemStreamReader">
<property name="delegate">
<bean class="org.springframework.batch.item.file.FlatFileItemReader">
<property name="lineMapper">
<bean class="org.springframework.batch.item.file.mapping.DefaultLineMapper">
<!-- split it -->
<property name="lineTokenizer">
<bean
class="org.springframework.batch.item.file.transform.DelimitedLineTokenizer">
<property name="names"
value="name,age,address,mobileno" />
<property name="delimiter">
<util:constant
static-field="org.springframework.batch.item.file.transform.DelimitedLineTokenizer.DELIMITER_TAB" />
</property>
</bean>
</property>
<property name="fieldSetMapper">
<bean
class="com.services.extractor.Mapper">
</bean>
</property>
</bean>
</property>
</bean>
<bean id="outputFileWriter"
class="org.springframework.batch.item.support.CompositeItemWriter"
scope="step">
<property name="delegates">
<list>
<ref bean="routeWriter" />
</list>
</property>
</bean>
<bean id="routeWriter"
class="com.services.extractor.processor.IngestionWriter"
scope="step">
</bean>
public class SynchronizedItemStreamReader
implements ResourceAwareItemReaderItemStream {
private FlatFileItemReader<T> delegate;
private Resource resource;
public void setDelegate(FlatFileItemReader<T> delegate) {
this.delegate = delegate;
}
/**
* This delegates to the read method of the <code>delegate</code>
*/
public synchronized T read()
throws Exception, UnexpectedInputException, ParseException, NonTransientResourceException {
return this.delegate.read();
}
public void close() {
this.delegate.close();
}
public void open(ExecutionContext executionContext) {
this.delegate.open(executionContext);
}
public void update(ExecutionContext executionContext) {
this.delegate.update(executionContext);
}
#Override
public void setResource(Resource resource) {
this.resource = resource;
}
writer class:
public class IngestionWriter implements ItemWriter<Person> {
#Override
public void write(List<? extends Person> items) throws IOException {
//logic to set into db
}
Here is the exception:
org.springframework.batch.item.ReaderNotOpenException:Reader must be open before it can be read.:org.springframework.batch.item.ReaderNotOpenException: Reader must be open before it can be read.
at org.springframework.batch.item.file.FlatFileItemReader.readLine(FlatFileItemReader.java:195)
at org.springframework.batch.item.file.FlatFileItemReader.doRead(FlatFileItemReader.java:173)
at org.springframework.batch.item.support.AbstractItemCountingItemStreamItemReader.read(AbstractItemCountingItemStreamItemReader.java:83)
at sun.reflect.GeneratedMethodAccessor73.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:317)
After implementing SynchronizedItemStreamReader exception:
org.springframework.batch.item.ReaderNotOpenException:Reader must be open before it can be read.:org.springframework.batch.item.ReaderNotOpenException: Reader must be open before it can be read.
at org.springframework.batch.item.file.FlatFileItemReader.readLine(FlatFileItemReader.java:195)
at org.springframework.batch.item.file.FlatFileItemReader.doRead(FlatFileItemReader.java:173)
at org.springframework.batch.item.support.AbstractItemCountingItemStreamItemReader.read(AbstractItemCountingItemStreamItemReader.java:83)
at .SynchronizedItemStreamReader.read(SynchronizedItemStreamReader.java:35)
at org.springframework.batch.item.file.MultiResourceItemReader.readFromDelegate(MultiResourceItemReader.java:140)
at org.springframework.batch.item.file.MultiResourceItemReader.readNextItem(MultiResourceItemReader.java:119)
at org.springframework.batch.item.file.MultiResourceItemReader.read(MultiResourceItemReader.java:108)
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:317)
at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:183)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:150)
at org.springframework.aop.support.DelegatingIntroductionInterceptor.doProceed(DelegatingIntroductionInterceptor.java:132)
at org.springframework.aop.support.DelegatingIntroductionInterceptor.invoke(DelegatingIntroductionInterceptor.java:120)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:204)
at com.sun.proxy.$Proxy47.read(Unknown Source)
Added reader and writer steps.
Am I missing something here?
Any help is greatly appreciated!!
Thanks!!!
AbstractItemCountingItemStreamItemReader implementations aren't thread-safe. You can try to solve it implementing your own reader and synchronizing methods that mutate shared state like close(), open() and update().
Related
I have a spring batch job where I need to get a value from database in a step and use that value in a reader in an other step . but I m getting an error saying :
'Invalid property 'id' of bean class [org.springframework.batch.core.scope.context.StepContext]: Bean property 'id' is not readable or has an invalid getter method: Does the return type of the getter match the parameter type of the setter?'
here I will put only the relevant part of my files to be clear , if need extra infos I can add it , thanks
xml config file:
<bean id="setter" class="fat.IdSetter" scope="step">
<property name="id" value="#{stepExecutionContext([id])}"></property>
</bean>
<bean id="reader"
class="org.springframework.batch.item.database.JdbcCursorItemReader" >
<property name="dataSource" ref="dataSource" />
<property name="sql" value="SELECT * FROM TABLE WHERE ID = ?" />
<property name="rowMapper">
<bean class="fat.RowMapper"></bean>
</property>
<property name="preparedStatementSetter" ref="setter"></property>
</bean>
<batch:job id="job">
<batch:step id="getId" next="loopStep">
<batch:tasklet ref="getId"></batch:tasklet>
</batch:step>
<batch:step id="loopStep">
<batch:tasklet>
<batch:chunk reader="reader" processor="processor"
writer="xmlWriter" commit-interval="1000">
</batch:chunk>
<batch:listeners>
<batch:listener ref="footerCallBack"></batch:listener>
<batch:listener ref="headerCallBack"></batch:listener>
</batch:listeners>
</batch:tasklet>
</batch:step>
</batch:job>
<bean id="getId" class="fat.GetId" >
<property name="restCall" ref="restCall"></property>
</bean>
the tasklet where I get the value of id :
public class GetId implements Tasklet {
#Override
public RepeatStatus execute(StepContribution contribution, ChunkContext chunkContext) throws Exception {
// here I call my web service to get data and put it in a Long variable named id
chunkContext.getStepContext().getStepExecution().getJobExecution().getExecutionContext().put("id",
id);
return RepeatStatus.FINISHED;
}
}
the prepared statement setter for id class:
public class IdSetter implements PreparedStatementSetter {
private Long id;
#Override
public void setValues(PreparedStatement ps) throws SQLException {
ps.setLong(1 , id);
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
}
I think the error because it didn t find the id parameter in the stepExecutionContext , any help is appreciated.
Your tasklet GetId puts the id in the job execution context. So your reader can get it from there as follows:
<bean id="reader" class="org.springframework.batch.item.database.JdbcCursorItemReader" scope="step" >
<property name="dataSource" ref="dataSource" />
<property name="sql" value="SELECT * FROM TABLE WHERE ID = #{jobExecutionContext[id]}" />
<property name="rowMapper">
<bean class="fat.RowMapper"></bean>
</property>
<!-- <property name="preparedStatementSetter" ref="setter"></property> --> // This is not needed
</bean>
Note that the reader should step scoped. With that, you don't need the bean named setter.
Another option is to pass the id as a job parameter and use it in the reader (See example here).
Exception in thread "main" org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'daoB2a': Invocation of init method failed; nested exception is java.lang.IllegalAccessError: tried to access class org.springframework.beans.PropertyMatches from class org.springframework.data.mapping.PropertyReferenceException
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1574)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:539)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:476)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:303)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:299)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:194)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:736)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:757)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:480)
at org.springframework.context.support.FileSystemXmlApplicationContext.<init>(FileSystemXmlApplicationContext.java:140)
at org.springframework.context.support.FileSystemXmlApplicationContext.<init>(FileSystemXmlApplicationContext.java:84)
at test.Main.main(Main.java:28)
Caused by: java.lang.IllegalAccessError: tried to access class org.springframework.beans.PropertyMatches from class org.springframework.data.mapping.PropertyReferenceException
at org.springframework.data.mapping.PropertyReferenceException.detectPotentialMatches(PropertyReferenceException.java:134)
at org.springframework.data.mapping.PropertyReferenceException.<init>(PropertyReferenceException.java:59)
at org.springframework.data.mapping.PropertyPath.<init>(PropertyPath.java:75)
at org.springframework.data.mapping.PropertyPath.create(PropertyPath.java:327)
at org.springframework.data.mapping.PropertyPath.create(PropertyPath.java:307)
at org.springframework.data.mapping.PropertyPath.from(PropertyPath.java:270)
at org.springframework.data.mapping.PropertyPath.from(PropertyPath.java:241)
at org.springframework.data.repository.query.parser.Part.<init>(Part.java:76)
at org.springframework.data.repository.query.parser.PartTree$OrPart.<init>(PartTree.java:235)
at org.springframework.data.repository.query.parser.PartTree$Predicate.buildTree(PartTree.java:373)
at org.springframework.data.repository.query.parser.PartTree$Predicate.<init>(PartTree.java:353)
at org.springframework.data.repository.query.parser.PartTree.<init>(PartTree.java:87)
at org.springframework.data.jpa.repository.query.PartTreeJpaQuery.<init>(PartTreeJpaQuery.java:61)
at org.springframework.data.jpa.repository.query.JpaQueryLookupStrategy$CreateQueryLookupStrategy.resolveQuery(JpaQueryLookupStrategy.java:95)
at org.springframework.data.jpa.repository.query.JpaQueryLookupStrategy$CreateIfNotFoundQueryLookupStrategy.resolveQuery(JpaQueryLookupStrategy.java:206)
at org.springframework.data.jpa.repository.query.JpaQueryLookupStrategy$AbstractQueryLookupStrategy.resolveQuery(JpaQueryLookupStrategy.java:73)
at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.<init>(RepositoryFactorySupport.java:416)
at org.springframework.data.repository.core.support.RepositoryFactorySupport.getRepository(RepositoryFactorySupport.java:206)
at org.springframework.data.repository.core.support.RepositoryFactoryBeanSupport.initAndReturn(RepositoryFactoryBeanSupport.java:251)
at org.springframework.data.repository.core.support.RepositoryFactoryBeanSupport.afterPropertiesSet(RepositoryFactoryBeanSupport.java:237)
at org.springframework.data.jpa.repository.support.JpaRepositoryFactoryBean.afterPropertiesSet(JpaRepositoryFactoryBean.java:92)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1633)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1570)
... 12 more
#Component("test")
public class JpaConfig {
#Autowired
daoB2a dao;
public daoB2a getDao() {
return dao;
}
public void setDao(daoB2a dao) {
this.dao = dao;
}
}
<jpa:repositories base-package="com.company.springdata.daos" />
<context:property-placeholder location="src/main/resources/application.properties"/>
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="${db.drivermanager}"/>
<property name="url" value="${db.url}"/>
<property name="password" value="${db.password}"/>
<property name="username" value="${db.username}"/>
</bean>
<bean id="hbAdapterBean" class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
<property name="showSql" value="true"/>
<property name="generateDdl" value="true"/>
<property name="databasePlatform" value="org.hibernate.dialect.MySQLDialect"/>
</bean>
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="packagesToScan" value="com.mycompany.springdata.entities"/>
<property name="jpaVendorAdapter" ref="hbAdapterBean"/>
</bean>
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory" />
</bean>
<context:component-scan base-package="com.mycompany.springdata.entities"/>
public class Main {
public static void main(String[] args) {
ApplicationContext app = new FileSystemXmlApplicationContext("src/main/resources/beans.xml");
System.out.println("read successfuly");
// JpaConfig user = (JpaConfig) app.getBean("test");
// System.out.println("user is "+user);
// System.out.println(""+user.getDao().save(new User("dskds", "sds", "dsds", "dsddskd")));
}
}
make sure you inject daoB2a bean in your xml file
;
I would like to invoke sftp:outbound-gateway from batch tasklet in order to download a file from sftp server.
I've seen other posts related to this subject but I'm not sure what am I doing wrong. Could anybody give me a hint based on my configuration? My batch works so the problem is just to ivoke the sftp component in batch step. I've marked the Spring Integration section with comment so it is easier to read just a relevant configuration.
I can see in my logs: DEBUG [o.s.i.e.SourcePollingChannelAdapter] Received no Message during the poll, returning 'false'. So I am not receiving a file but why?
Thanks in advance for your time spend on analysis!
<bean id="ftsSftpClientFactory" class="org.springframework.integration.sftp.session.DefaultSftpSessionFactory">
<property name="host" value="${my.import.sftp.localhost}"/>
<property name="user" value="${my.import.sftp.username}"/>
<property name="password" value="${my.import.sftp.passwort}"/>
</bean>
<!-- Start: Spring Integration -->
<int:channel id="replyChannel" >
<int:queue/>
</int:channel>
<int:channel id="requestChannel" />
<int-sftp:outbound-gateway id="sftpGateway"
session-factory="ftsSftpClientFactory"
request-channel="requestChannel"
reply-channel="replyChannel"
auto-startup="true"
command="get"
command-options="-P"
expression="payload"
remote-directory="."
local-directory="${my.import.sftp.copy.file.destinationpath}">
</int-sftp:outbound-gateway>
<bean name="copyFileTasklet" class="com.mydomain.CopyFileTasklet">
<property name="channel" ref="replyChannel" />
<property name="pollableChannel" ref="requestChannel" />
</bean>
<!-- Start: Spring Batch -->
<bean name="myImportTask" class="com.mydomain.MyImportTask">
<property name="job" ref="unternehmungImportJob"/>
<property name="jobLauncher" ref="jobLauncher"/>
</bean>
<bean id="jobDetail"
class="com.mydomain.MyImportJob">
<property name="myImportTask" ref="myImportTask" />
</bean>
<!--suppress SpringBatchModel -->
<batch:job id="myImportJob">
<batch:step id="copy-file-step" next="my-import-step">
<batch:tasklet ref="copyFileTasklet"/>
</batch:step>
<batch:step id="my-import-step">
<batch:tasklet>
<batch:chunk reader="myItemReader"
writer="myItemWriter"
commit-interval="10000">
<!--
skip-limit="10000"
<batch:skippable-exception-classes>
<batch:include class="java.lang.Exception"/>
<batch:exclude class="java.io.FileNotFoundException"/>
</batch:skippable-exception-classes> -->
</batch:chunk>
<batch:transaction-attributes isolation="DEFAULT" propagation="REQUIRED"/>
</batch:tasklet>
</batch:step>
</batch:job>
<bean id="myItemReader" scope="step" class="org.springframework.batch.item.file.FlatFileItemReader">
<property name="linesToSkip" value="1"/>
<property name="encoding" value="${my.import.batch.encoding}" />
<property name="resource" value="${my.import.batch.input.resource}"/>
<property name="lineMapper">
<bean class="org.springframework.batch.item.file.mapping.DefaultLineMapper">
<property name="lineTokenizer" ref="lineTokenizer"/>
<property name="fieldSetMapper">
<bean class="com.mydomain.MyImportMapper"/>
</property>
</bean>
</property>
</bean>
<bean id="myItemWriter" class="com.mydomain.MyItemWriter">
<property name="myApplicationService" ref="defaultmyApplicationService" />
</bean>
<bean id="lineTokenizer" class="com.mydomain.DelimitedLineTokenizerWithEOF">
<property name="delimiter" value="${my.import.batch.delimiter}" />
<property name="eofMarker" value="${my.import.batch.eof.marker}" />
</bean>
public class CopyFileTasklet implements Tasklet {
private MessageChannel requestChannel;
private PollableChannel replyChannel;
public void setRequestChannel(MessageChannel requestChannel) {
this.requestChannel = requestChannel;
}
public void setReplyChannel(PollableChannel replyChannel) {
this.replyChannel = replyChannel;
}
#Override
public RepeatStatus execute(StepContribution stepContribution, ChunkContext chunkContext) throws Exception {
Message<?> result = replyChannel.receive(10000);
Object file = result.getPayload();
return RepeatStatus.FINISHED;
}
}
Your issue that you don't inititate Integration Flow from your custom Tasklet. Of course you can't receive anything from the replyChannel, if you haven't sent request before.
If you just need to process Integration Flow and get result from it, it would be better to use POJI <gateway> from that Tasklet:
public interface SftpGateway {
File download(String fileName);
}
<gateway id="sftpGateway" service-interface="com.my.proj.SftpGateway"
default-request-channel="requestChannel"/>
<bean name="copyFileTasklet" class="com.mydomain.CopyFileTasklet">
<property name="sftpGateway" ref="sftpGateway" />
</bean>
Something like that.
With Httpclient 3 my Spring bean definition was
<bean id="messageSender"
class="org.springframework.ws.transport.http.CommonsHttpMessageSender">
<constructor-arg>
<bean class="org.apache.commons.httpclient.HttpClient">
<constructor-arg>
<bean
class="org.apache.commons.httpclient.MultiThreadedHttpConnectionManager">
<property name="params">
<bean
class="org.apache.commons.httpclient.params.HttpConnectionManagerParams">
<property name="defaultMaxConnectionsPerHost" value="XX" />
<property name="maxTotalConnections" value="XX" />
<property name="staleCheckingEnabled" value="false" />
<property name="tcpNoDelay" value="false" />
<property name="soTimeout" value="XXXXX" />
<property name="connectionTimeout"
value="XXXX" />
</bean>
</property>
</bean>
</constructor-arg>
</bean>
</constructor-arg>
I want a similar bean configuration with the httpclient 4.3 classes.
I needed NTLMv2 authentication on my connection and I was able to succesfully use 4.x by configuring spring with the classes attached to this issue: https://jira.spring.io/browse/SWS-563
Here's a piece of my #Configuration:
#Bean public WebServiceTemplate webserviceTemplate() {
WebServiceTemplate webserviceTemplate = new WebServiceTemplate();
webserviceTemplate.setMessageSender(messageSender());
return webserviceTemplate;
}
#Bean public WebServiceMessageSender messageSender() {
HttpClientMessageSender messageSender = new HttpClientMessageSender();
// do 4.x specific configuration
return messageSender;
}
I am trying to update the user_info table with the new password using EntityManager.merge(), but it is not getting committed. Below is my code:
app-cofig.xml:
<!-- Application Message Bundle -->
<bean id="messageSource" class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
<property name="basename" value="/WEB-INF/messages" />
<property name="cacheSeconds" value="300" />
</bean>
<bean id="loginValidator" class="com.sbi.llms.validator.LoginValidator"/>
<bean id="loginProcessor" class="com.sbi.llms.processor.LoginProcessor">
<property name="userDao" ref="userDao"/>
</bean>
<!-- Resolves view names to protected .jsp resources within the /WEB-INF/views directory -->
<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/jsp/"/>
<property name="suffix" value=".jsp"/>
</bean>
<bean id="forgetProcessor" class="com.test.ForgetPasswordProcessor">
<property name="forgetDao" ref="forgetDao"/>
</bean>
<bean name="/popup_forgot_password.html" class="com.test.ForgetPasswordController">
<property name="processor" ref="forgetProcessor"/>
<property name="commandClass" value="com.test.ForgetPasswordDTO"/>
<property name="commandName" value="btn_reset"/>
<property name="formView" value="popup_forgot_password"/>
<property name="successView" value="popup_forgot_password"/>
<property name="validator">
<bean class="com.test.LoginValidator"/>
</property>
</bean>
<bean id="myDataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="oracle.jdbc.OracleDriver"/>
<property name="url" value="jdbc:oracle:thin:#10.0.27.105:1521/LLMSDB1"/>
<property name="username" value="llms"/>
<property name="password" value="llms12"/>
</bean>
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager" p:entityManagerFactory-ref="entityManagerFactory" />
<bean id="entityManager" class="org.springframework.orm.jpa.support.SharedEntityManagerBean" p:entityManagerFactory-ref="entityManagerFactory" />
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="dataSource" ref="myDataSource" />
<property name="persistenceUnitName" value="cccPersistenceUnit" />
<property name="jpaDialect" ref="jpaDialect" />
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.EclipseLinkJpaVendorAdapter">
<property name="databasePlatform" value="org.eclipse.persistence.platform.database.OraclePlatform"/>
<property name="showSql" value="true"/>
</bean>
</property>
<property name="loadTimeWeaver">
<bean class="org.springframework.instrument.classloading.InstrumentationLoadTimeWeaver" />
</property>
</bean>
<bean id="baseJPADao" class="com.sbi.llms.dao.jpa.BaseJPADAO">
<property name="entityManager" ref="entityManager"/>
</bean>
<bean id="userDao" class="com.sbi.llms.dao.UserDAO">
<property name="entityManager" ref="entityManager"/>
</bean>
<bean id="forgetDao" class="com.test.ForgetPasswordDAO">
<property name="entityManager" ref="entityManager"/>
</bean>
<bean id="jpaDialect" class="org.springframework.orm.jpa.vendor.EclipseLinkJpaDialect" />
persistance.xml
<?xml version="1.0" encoding="UTF-8" ?>
<persistence xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd"
version="2.0" xmlns="http://java.sun.com/xml/ns/persistence">
<persistence-unit name="cccPersistenceUnit" transaction-type="RESOURCE_LOCAL"> <!-- "RESOURCE_LOCAL" -->
<provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
<mapping-file>META-INF/LoginModel.xml</mapping-file>
<mapping-file>META-INF/eclipselink-orm.xml</mapping-file>
<class>com.sbi.llms.model.LoginModel</class>
<class>com.test.ForgetPasswordModel</class>
<properties>
<!-- Configure cache size. -->
<property name="eclipselink.cache.size.default" value="1000" />
<!-- Configure simple SQL logging for demonstration. -->
<property name="eclipselink.logging.level" value="FINE" />
<property name="eclipselink.logging.thread" value="false" />
<property name="eclipselink.logging.session" value="false" />
<property name="eclipselink.logging.exceptions" value="false" />
<property name="eclipselink.logging.timestamp" value="false" />
</properties>
</persistence-unit>
</persistence>
Here is my DAO
public class ForgetPasswordDAO {
private Vector loginResult = null;
private int resultTrue = 1;
private int resultFalse = 0;
protected EntityManager entityManager;
JpaEntityManager jpaEntityManager;
public ForgetPasswordDAO() {
}
public EntityManager getEntityManager() {
return entityManager;
}
public void setEntityManager(EntityManager entityManager) {
this.entityManager = entityManager;
}
public Integer fetchUser(ForgetPasswordModel model) throws Exception {
try {
ForgetPasswordDTO DTO ;
if(model == null) {
throw new Exception("102");
}
Integer result = 0;
String userName = model.getUser_id();
String dob = model.getDob();
System.out.println("UserDTO " + model.getUser_id() + " "
+ model.getDob());
ForgetPasswordModel forgetModel = null;
System.out.println(entityManager.isOpen()+">>");
forgetModel = entityManager.find(ForgetPasswordModel.class, model.getUser_id());
entityManager.close();
System.out.println("UserDAO " + forgetModel.getUser_id() + " DOB "
+ forgetModel.getDob()+" EMAIL_ID "+forgetModel.getEmail_id()+" PASSWORD "+forgetModel.getPasswd());
if(model.getDob().equals(forgetModel.getDob())) {
System.out.println("USER VALID , CAN PROCEED WITH PASSWORD RESET");
String passwd = GenerateRandomPassword.generateRandomPassword();
System.out.println("generated password is" +passwd);
entityManager.getTransaction().begin();
forgetModel.setPasswd(passwd);
entityManager.merge(forgetModel);
entityManager.getTransaction().commit();
System.out .println("updated password is "+forgetModel.getPasswd());
String email=forgetModel.getEmail_id();
ForgetPasswordSendMail.SendMail( email, passwd);
result=1;
}
else
{
System.out.println("USER InVALID , Please Provide Valid Data");
}
return result;
} catch (Exception e) {
throw new Exception("103", e);
}
}
}
When I run the above code I get the following error:
java.lang.IllegalStateException: Not allowed to create transaction on shared EntityManager - use Spring transactions or EJB CMT instead
org.springframework.orm.jpa.SharedEntityManagerCreator$SharedEntityManagerInvocationHandler.invoke(SharedEntityManagerCreator.java:198)
com.sun.proxy.$Proxy6.getTransaction(Unknown Source)
com.test.ForgetPasswordDAO.fetchUser(ForgetPasswordDAO.java:81)
com.test.ForgetPasswordProcessor.execute(ForgetPasswordProcessor.java:52)
com.test.ForgetPasswordController.onSubmit(ForgetPasswordController.java:56)
org.springframework.web.servlet.mvc.SimpleFormController.processFormSubmission(SimpleFormController.java:272)
org.springframework.web.servlet.mvc.AbstractFormController.handleRequestInternal(AbstractFormController.java:268)
org.springframework.web.servlet.mvc.AbstractController.handleRequest(AbstractController.java:153)
org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter.handle(SimpleControllerHandlerAdapter.java:48)
org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:790)
org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:719)
org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:644)
org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:560)
javax.servlet.http.HttpServlet.service(HttpServlet.java:641)
javax.servlet.http.HttpServlet.service(HttpServlet.java:722)
Since you are using Spring, you need to use Spring transactions, not JPA transactions.
You need to declare the transaction in Spring, or access the EntityManager directly, not through Spring.