This question already has answers here:
Why is my Spring #Autowired field null?
(21 answers)
Closed 6 years ago.
Hi Friends i am creating a simple application using Spring and JPA over Hibernate but i am getting a Null Pointer Exception while running the app as the beans are not getting initialised.Below is my application-context.xml
<beans>
<mvc:annotation-driven/>
<bean id="entityManagerFactoryBean" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="packagesToScan" value="com.sms.examination.entity.*" />
</property>
<property name="jpaProperties">
<props>
<prop key="hibernate.hbm2ddl.auto">validate</prop>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</prop>
</props>
</property>
</bean>
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver" />
<property name="url" value="jdbc:mysql://localhost:3306/examination" />
<property name="username" value="root" />
<property name="password" value="" />
</bean>
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactoryBean" />
</bean>
<tx:annotation-driven/>
</beans>
NameDao Interface :-
package com.sms.examination.dao;
import java.util.List;
import com.sms.examination.entity.Name;
public interface NameDao {
public List<Name> findAll();
}
Implementation
package com.sms.examination.dao;
import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;
import com.sms.examination.entity.Name;
#Repository
#Transactional
#Component
public class NamedaoImpl implements NameDao
{
#PrsistenceContext
private EntityManager entityManagerFactoryBean;
public List<Name> findAll() {
if(entityManagerFactoryBean==null)
{
System.out.println("manager is null");
}
else
System.out.println("manager is not null");
List<Name> names = entityManagerFactoryBean.createQuery("select s from Name s",Name.class).getResultList();
return names;
}
}
Controller
package com.sms.examination.controller;
import java.util.*;
import com.sms.examination.dao.NameDao;
import com.sms.examination.dao.NamedaoImpl;
import com.sms.examination.entity.Name;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class NameController {
#Autowired
private NameDao namedao;
#Autowired
private NamedaoImpl name;
public void getNames(){
List<Name> namelist=new ArrayList<Name>();
if(namedao==null)
{
System.out.println("name doa is null");
}
namelist=namedao.findAll();
Iterator<Name> it=namelist.iterator();
while(it.hasNext())
{
System.out.println(it.hasNext());
}
}
public static void main(String[] args) {
ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("classpath:application-context.xml");
NameController names=new NameController();
names.getNames();
}
}
While running the Controller class i am getting the below output.Please help
name doa is null which is because the NameDao class has not been initailised.
You need to add component scan in your application context
<context:component-scan base-package="com.sms.examination" />
Related
I have written the below code to implment the transaction management of spring using #transactional annotation. I still feel some changes are required
in my DAO layer. May I know what changes are required . Thanks in advance
#Controller
public class RestController {
#Autowired
DataServices dataServices;
#RequestMapping(value = "/v1/dist_list/{emailId}/members", method = RequestMethod.GET)
public #ResponseBody String getDistributionListMember(#PathVariable String emailId) throws Exception, SpringException {
String retStatus = null;
retStatus = dataServices.getDistributionListMember(emailId, callerId);
]
}
}
DataServices.java
package com.uniteid.services;
import com.uniteid.model.AIWSuser;
public interface DataServices {
public String getDistributionListMember(final String emailId, final String callerID) throws Exception;
}
Below is my service layer where I added the trasactional attribute
package com.uniteid.services;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.uniteid.dao.DataDao;
import com.uniteid.model.AIWSuser;
#Service("dataService")
public class DataServicesImpl implements DataServices {
#Autowired
DataDao dataDao;
#Transactional
public String getDistributionListMember(String emailId, String callerID)
throws Exception {
return dataDao.getDistributionListMember(emailId, callerID);
}
}
Below is my spring-config file
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
xmlns:util="http://www.springframework.org/schema/util" xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.2.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.0.xsd"
xmlns:tx="http://www.springframework.org/schema/tx">
<context:component-scan base-package="com.uniteid.controller" />
<mvc:annotation-driven
content-negotiation-manager="contentNegociationManager" />
<bean
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="location" value="classpath:uniteidrest.properties" />
<property name="systemPropertiesModeName" value="SYSTEM_PROPERTIES_MODE_OVERRIDE" />
</bean>
<bean id="dataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="oracle.jdbc.driver.OracleDriver" />
<property name="url">
<value>${eidms.url}</value>
</property>
<property name="username">
<value>${eidms.username}</value>
</property>
<property name="password">
<value>${eidms.password}</value>
</property>
</bean>
<!-- <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="oracle.jdbc.driver.OracleDriver"
/> <property name="url" value="jdbc:oracle:thin:#nyvm0467.ptc.un.org:1521:EIDMSUAT"
/> <property name="username" value="DBO_EIDMSUAT" /> <property name="password"
value="NewPassDBO_EIDMSUAT" /> </bean> -->
<bean id="contentNegociationManager"
class="org.springframework.web.accept.ContentNegotiationManagerFactoryBean">
<property name="defaultContentType" value="application/json" />
<property name="ignoreAcceptHeader" value="true" />
</bean>
<bean id="sessionFactory"
class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="annotatedClasses">
<list>
<value>com.uniteid.model.User</value>
</list>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.Oracle10gDialect</prop>
<prop key="hibernate.connection.pool_size">10</prop>
</props>
</property>
</bean>
<bean id="txManager"
class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
<bean id="persistenceExceptionTranslationPostProcessor"
class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor" />
<bean id="dataDao" class="com.uniteid.dao.DataDaoImpl"></bean>
<bean id="dataServices" class="com.uniteid.services.DataServicesImpl"></bean>
<bean id="transactionManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource" />
</bean>
<tx:annotation-driven transaction-manager="transactionManager" />
</beans>
It still feel I have not implemented the Transactional management properly in the below code. May I know what part of the code can be removed for me to implement it
package com.uniteid.dao;
import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.SQLException;
import java.sql.Types;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import org.apache.log4j.Logger;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.jdbc.Work;
import org.springframework.beans.factory.annotation.Autowired;
import com.uniteid.controller.RestController;
import com.uniteid.model.AIWSuser;
import com.uniteid.model.User;
public class DataDaoImpl implements DataDao
{
#Autowired
\
SessionFactory sessionFactory;
Session session = null;
Transaction tx = null;
static final Logger logger = Logger.getLogger(DataDaoImpl.class);
public String getDistributionListMember(final String emailId, final String callerID) throws Exception {
session = sessionFactory.openSession();
tx = session.beginTransaction();
final String[] returnVal2 = { "" };
session.doWork(new Work() {
public void execute(Connection connection) throws SQLException {
CallableStatement stmt = null;
String returnVal = "";
stmt = connection.prepareCall("{?=call WS_Distributionlistmember(?,?)}");
stmt.registerOutParameter(1, Types.VARCHAR);
stmt.setString(2, emailId);
stmt.setString(3, callerID);
stmt.execute();
returnVal = stmt.getString(1);
logger.info("RETURN VALUE in getDistributionListMember method :::::: " + returnVal);
returnVal2[0] = returnVal;
logger.info("Return Value " + returnVal);
stmt.close();
}
});
tx.commit();
session.close();
return returnVal2[0];
}
}
Your code:
public String getDistributionListMember(final String emailId, final String callerID) throws Exception {
session = sessionFactory.openSession();//This is bad
tx = session.beginTransaction();//This is bad
tx.commit();//This is bad
session.close();//This is bad
Correct should be:
public String getDistributionListMember(final String emailId, final String callerID) throws Exception {
session = sessionFactory.getCurrentSession();//good way
It is because you told spring to autowired sessionFactory and from now on spring is managing your hibernate session not you. So getCurrentSession() is correct way.
#M. Deinum Thanks to point it out.
Remove bean declaration for bean id transactionManager and set txManager instead of transactionManager in transaction-manager value. As you are using hibernate with spring so HibernateTransactionManager should be used instead of DatabaseTransactionManager to define transaction boundary. DatabaseTransactionManager is used when you directly interact with data source without using any ORM or JPA framework.
In your service class define transaction boundary for method as below annotation
#Transactional(readOnly = true, propagation = Propagation.SUPPORTS)
I am trying to integrate monodb with my springBoot application 1st time, But I am stuck with the error
My code is below
package com.myProject.customerview;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.ImportResource;
import org.springframework.data.mongodb.repository.config.EnableMongoRepositories;
import org.springframework.scheduling.annotation.EnableScheduling;
#EnableScheduling
#ImportResource("classpath*:spring/application-context.xml")
#ComponentScan({ "com.myproject.payments", "com.myproject.customerview" })
// #EnableJpaRepositories("com.myproject.customerview.repository")
#EnableMongoRepositories
#SpringBootApplication
public class CustomerViewApplication {
public static void main(String args[]) {
SpringApplication application = new SpringApplication(
CustomerViewApplication.class);
application.run(args);
}
}
and Controller
package com.myproject.customerview.controller;
import javax.servlet.http.HttpServletRequest;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import com.myproject.customerview.constants.RestURIConstants;
import com.myproject.customerview.response.ServiceResponse;
import com.myproject.customerview.service.CustomerViewService;
#RestController
#RequestMapping(RestURIConstants.CUSTOMER_VIEW)
public class CustomerViewController {
#Autowired
private CustomerViewService customerViewService ;
#RequestMapping(value = RestURIConstants.USER_ID, method = RequestMethod.GET)
public ServiceResponse<String> getMirrorAccountReport(
#PathVariable("userId") String userId, HttpServletRequest servletRequest)
throws Exception {
ServiceResponse<String> serviceResponse = new ServiceResponse<String>();
String response = "success:" ;
customerViewService.saveCustomerViewEntity();
serviceResponse.setResponse(response);
return serviceResponse;
}
}
service
package com.myproject.customerview.service.impl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.myproject.customerview.entity.CustomerViewEntity;
import com.mmyproject.customerview.repository.CustomerViewRepository;
import com.myproject.customerview.service.CustomerViewService;
#Service
public class CustomerviewServiceImpl implements CustomerViewService {
#Autowired
private CustomerViewRepository customerRepository ;
#Override
public void saveCustomerViewEntity() {
CustomerViewEntity entity = new CustomerViewEntity() ;
//setting data in enity....
customerRepository.saveCustomerView(entity);
}
}
dao interface layer
package com.myproject.customerview.dao;
import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
import org.springframework.data.domain.Sort;
import com.myproject.customerview.entity.CustomerViewEntity;
public interface CustomerViewMongoDao {
public void saveCustomerView(CustomerViewEntity entity) ;
}
its impl
package com.myproject.customerview.dao.impl;
import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.stereotype.Repository;
import com.myproject.customerview.constants.CustomerViewConstants;
import com.myproject.customerview.dao.CustomerViewMongoDao;
import com.myproject.customerview.entity.CustomerViewEntity;
#Repository
public class CustomerViewMongoDaoImpl implements CustomerViewMongoDao{
#Autowired
MongoTemplate mongoTemplate ;
#Override
public void saveCustomerView(CustomerViewEntity entity) {
mongoTemplate.insert(entity, CustomerViewConstants.CUSTOMER_VIEW_COLLECTION);
}
}
its repository
package com.myproject.customerview.repository;
import org.springframework.data.mongodb.repository.MongoRepository;
import com.myproject.customerview.dao.CustomerViewMongoDao;
import com.myproject.customerview.entity.CustomerViewEntity;
public interface CustomerViewRepository extends MongoRepository<CustomerViewEntity,String>, CustomerViewMongoDao {
}
and application-context.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mybatis="http://mybatis.org/schema/mybatis-spring" xmlns:task="http://www.springframework.org/schema/task"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:mongo="http://www.springframework.org/schema/data/mongo"
xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd
http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-3.2.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://mybatis.org/schema/mybatis-spring http://mybatis.org/schema/mybatis-spring.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.2.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd
http://www.springframework.org/schema/data/mongo http://www.springframework.org/schema/data/mongo/spring-mongo-1.5.xsd">
<mvc:annotation-driven />
<mvc:resources mapping="/resources/**" location="classpath:/resources" />
<bean id="imsPlaceholderConfig" class="com.myproject.customerview.utils.SpringPropertiesUtil">
<property name="systemPropertiesModeName" value="SYSTEM_PROPERTIES_MODE_OVERRIDE" />
<property name="locations">
<list>
<value>file:${config.path}/app.properties</value>
<value>file:${config.path}/api.properties</value>
<value>file:${config.path}/db.properties</value>
<value>classpath*:*application.properties</value>
</list>
</property>
</bean>
<bean
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/views/" />
<property name="suffix" value=".html" />
</bean>
<!-- <mongo:mongo replica-set="127.0.0.1:27017,127.0.0.1:27017,127.0.0.1:27017" id = "mongo" />
<mongo:db-factory dbname="customer_view" mongo-ref="mongo" id="mongoDbFactory"/>
<bean id="mongoTemplate" class="org.springframework.data.mongodb.core.MongoTemplate">
<constructor-arg name="mongoDbFactory" ref="mongoDbFactory" />
</bean>
<mongo:repositories base-package="com.myproject.customerview.repository" />
-->
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
destroy-method="close">
<property name="driverClassName"
value="${payment.customerview.database.driverClassName}" />
<property name="url" value="${payment.customerview.database.url}" />
<property name="username" value="${payment.customerview.database.username}" />
<property name="password" value="${payment.customerview.database.password}" />
<property name="maxActive" value="${payment.customerview.database.maxactive}" />
<property name="maxWait" value="${payment.customerview.database.maxwait}" />
<property name="maxIdle" value="${payment.customerview.database.maxIdle}" />
<property name="initialSize" value="${payment.customerview.database.inititalsize}" />
<property name="minIdle" value="${payment.customerview.database.minIdle}" />
<property name="timeBetweenEvictionRunsMillis"
value="${payment.customerview.database.timebetweenevictionrunsmillis}" />
<property name="minEvictableIdleTimeMillis"
value="${payment.customerview.database.minevictableidletimemillis}" />
</bean>
<!-- MyBatis related beans -->
<bean id="sqlSessionFactoryMybatis" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="configLocation" value="classpath:myBatis/sqlmap-config.xml" />
</bean>
<bean name="myBatisIMSDB" id="myBatisIMSDB"
class="org.mybatis.spring.SqlSessionTemplate">
<constructor-arg index="0" ref="sqlSessionFactoryMybatis" />
<constructor-arg index="1" value="REUSE" />
</bean>
<tx:annotation-driven transaction-manager="transactionManager" />
<bean id="transactionManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource" />
</bean>
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage"
value="com.myproject.customerview.dao.mapper" />
<property name="sqlSessionTemplateBeanName" value="myBatisIMSDB"></property>
</bean>
</beans>
I am getting following error.
java.lang.IllegalStateException: Failed to introspect annotations: class org.springframework.boot.autoconfigure.data.mongo.MongoRepositoriesAutoConfigureRegistrar$EnableMongoRepositoriesConfiguration
I have wrongly added this dependency in my pom.xml
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-mongodb</artifactId>
<version>1.8.0.RELEASE</version>
</dependency>
instead of this when i used
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-mongodb</artifactId>
</dependency>
my projects starts working fine.
My data is like this
UserId,UserData
1,data11
1,data12
2,data21
3,data31
The question is, how I can make the spring batch itemreader read multiple lines and map to object like
Map < userid, List < userdata > >
Steps to follow:
create a custom Item Writer class by implementing ItemWriter where we have implemented a logic to store User object in Map<String,List<String>> because a single user can have multiple associated data
package com.spring.batch.domain;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.springframework.batch.item.ItemWriter;
public class UserItemWriter implements ItemWriter<User> {
private static Map<String, List<String>> userMap = new HashMap<String, List<String>>();
public void write(List<? extends User> users) throws Exception {
for (User user : users) {
List<String> list = userMap.get(user.getUserId());
if (list == null) {
list = new ArrayList<String>();
}
list.add(user.getUserData());
userMap.put(user.getUserId(), list);
}
}
public static Map<String, List<String>> getUserMap() {
return userMap;
}
}
Plain User POJO class having two fieldsuserId anduserData
package com.spring.batch.domain;
public class User {
private String userId;
private String userData;
public String getUserId() {
return userId;
}
public void setUserId(String userId) {
this.userId = userId;
}
public String getUserData() {
return userData;
}
public void setUserData(String userData) {
this.userData = userData;
}
}
Main class to run the job
package com.spring.batch.main;
import java.util.List;
import java.util.Map;
import org.springframework.batch.core.Job;
import org.springframework.batch.core.JobParametersBuilder;
import org.springframework.batch.core.JobParametersInvalidException;
import org.springframework.batch.core.launch.JobLauncher;
import org.springframework.batch.core.repository.JobExecutionAlreadyRunningException;
import org.springframework.batch.core.repository.JobInstanceAlreadyCompleteException;
import org.springframework.batch.core.repository.JobRestartException;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.spring.batch.domain.UserItemWriter;
public class Main {
public static void main(String[] args) throws BeansException,
JobExecutionAlreadyRunningException, JobRestartException,
JobInstanceAlreadyCompleteException, JobParametersInvalidException {
ApplicationContext appContext = new ClassPathXmlApplicationContext(
"config/application-context.xml");
JobLauncher jobLauncher = (JobLauncher) appContext.getBean("jobLauncher");
jobLauncher.run(
(Job) appContext.getBean("job"),
new JobParametersBuilder().addString("input.file.name",
"file:src/main/resources/data/input.csv").toJobParameters());
Map<String,List<String>> userMap=UserItemWriter.getUserMap();
for (String userId : userMap.keySet()) {
System.out.println(userId + ":" + userMap.get(userId));
}
}
}
application-context.xml:
<?xml version="1.0" encoding="UTF-8"?>
<beans ...>
<import resource="jobs.xml" />
<bean id="jobLauncher"
class="org.springframework.batch.core.launch.support.SimpleJobLauncher">
<property name="jobRepository" ref="jobRepository" />
</bean>
<bean id="jobRepository"
class="org.springframework.batch.core.repository.support.MapJobRepositoryFactoryBean">
<property name="transactionManager" ref="transactionManager" />
</bean>
<bean id="transactionManager"
class="org.springframework.batch.support.transaction.ResourcelessTransactionManager" />
</beans>
jobs.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans ...>
<job id="job" restartable="false"
xmlns="http://www.springframework.org/schema/batch">
<step id="step1">
<tasklet>
<chunk reader="csvItemReader" writer="userItemWriter"
commit-interval="2">
</chunk>
</tasklet>
</step>
</job>
<bean id="userItemWriter" class="com.spring.batch.domain.UserItemWriter"
scope="step" />
<bean id="csvItemReader" class="org.springframework.batch.item.file.FlatFileItemReader"
scope="step">
<property name="lineMapper">
<bean class="org.springframework.batch.item.file.mapping.DefaultLineMapper">
<property name="lineTokenizer">
<bean
class="org.springframework.batch.item.file.transform.DelimitedLineTokenizer">
<property name="names" value="userId,userData" />
</bean>
</property>
<property name="fieldSetMapper">
<bean
class="org.springframework.batch.item.file.mapping.BeanWrapperFieldSetMapper">
<property name="prototypeBeanName" value="user" />
</bean>
</property>
</bean>
</property>
<property name="linesToSkip" value="1" />
<property name="resource" value="#{jobParameters['input.file.name']}" />
</bean>
<bean id="user" class="com.spring.batch.domain.User" scope="prototype" />
</beans>
input.csv
UserId,UserData
1,data11
1,data12
2,data21
3,data31
Project structure screenshot (Maven)
All - In the Spring 3.0, in the applicationContext.xml .... are we supposed to have the bean property name and the reference value to be the same ? If I give a different value, it returns null object. But on giving the same value, it works. For my project, i am supposed to give different values for them. Kindly help. bye, HS
This works: (same values)
<bean id="MNCWIRAdminBaseAction" class="com.megasoft.wiradmin.web.action.WIRAdminBaseAction">
<property name="cacheDelegate">
<ref bean="cacheDelegate" />
</property>
</bean>
This doesn't work: (different values)
<bean id="MNCWIRAdminBaseAction" class="com.megasoft.wiradmin.web.action.WIRAdminBaseAction">
<property name="cacheDelegate">
<ref bean="MNCCacheDelegate" />
</property>
</bean>
bye, HS
My Full Code here:
WIRAdminBaseAction.java ---> my base action
AuthenticateAction.java ---> my java file that calls the bean here
applicationContext.xml --> system's applicationcontext file
applicationContext_MNC.xml ---> my applicationContext for a specific company ... this is getting loaded by my java file, which gets invoked by the web.xml file.
CacheDelegate.java
StatusDBDAO.java
PreXMLWebApplicationContext.java ----> loads my applicationContext file for the specific company.
****** applicationContext.xml ******
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.0.xsd ">
<bean name="exceptionHandler" class="com.megasoft.wir.eStatement.web.interceptor.WIRExceptionHandlerInterceptor"/>
<bean name="security" class="com.megasoft.wir.eStatement.web.interceptor.SecurityInterceptor"/>
<bean name="permission" class="com.megasoft.wir.eStatement.web.interceptor.PermissionInterceptor"/>
<!-- AutoProxies -->
<bean name="loggingAutoProxy" class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator">
<property name="interceptorNames">
<list>
<value>base</value>
<value>exceptionHandler</value>
<value>security</value>
<value>permission</value>
</list>
</property>
</bean>
</beans>
****** applicationContext_MNC.xml ******
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN"
"http://www.springframework.org/dtd/spring-beans.dtd">
<beans>
<bean id="MNCWIRAdminBaseAction" class="com.megasoft.wiradmin.web.action.WIRAdminBaseAction">
<property name="cacheDelegate">
<ref bean="MNCCacheDelegate" />
</property>
</bean>
<bean id="MNCCacheDelegate" class="com.megasoft.wiradmin.delegate.CacheDelegate" >
<property name="statusDBDAO"><ref bean="MNCStatusDBDAO" /></property>
</bean>
<bean id="MNCStatusDBDAO" class="com.megasoft.wiradmin.dao.StatusDBDAO">
<property name="dataSource">
<ref bean="MNCAdminDataSource" />
</property>
</bean>
<!-- database configuration from property file -->
<bean id="MNCAdminDataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"
destroy-method="close" lazy-init="default" autowire="default" dependency-check="default">
<property name="driverClass" value="${jdbc.driver}" ></property>
<property name="jdbcUrl" value="${admin.jdbc.url}" ></property>
<property name="user" value="${admin.jdbc.user}" ></property>
<property name="password" value="${admin.jdbc.password}" ></property>
<property name="initialPoolSize" value="3" ></property>
<property name="minPoolSize" value="3" ></property>
<property name="maxPoolSize" value="25" ></property>
<property name="acquireIncrement" value="1" ></property>
<property name="acquireRetryDelay" value="1000" ></property>
<property name="debugUnreturnedConnectionStackTraces" value="true" ></property>
<property name="maxIdleTime" value="300" ></property>
<property name="unreturnedConnectionTimeout" value="300000" ></property>
<property name="preferredTestQuery" value="SELECT COUNT(*) FROM LOCALE_CODE" ></property>
<property name="checkoutTimeout" value="300000" ></property>
<property name="idleConnectionTestPeriod" value="600000" ></property>
</bean>
<!-- this bean is set to map the constants which needs to be configured as per
the environment to the java constants file -->
<bean id="envConstantsConfigbean" class="com.megasoft.wiradmin.util.constants.Environm entConstantsSetter">
<property name="loginUrl" value="${login.url}"/>
<property name="logoutIR" value="${logout.from.image.retrieval}"/>
<property name="adminModuleUrl" value="${admin.url}"/>
<property name="adminUrlSym" value="${admin.url.sym}"/>
<property name="envProperty" value="${env.property}"/>
</bean>
</beans>
****** AuthenticateAction.java ******
package com.megasoft.wiradmin.web.action;
import java.net.UnknownHostException;
import java.sql.SQLException;
import org.bouncycastle.crypto.CryptoException;
import org.springframework.context.ApplicationContext;
import org.springframework.dao.DataAccessException;
import org.springframework.web.context.support.WebApplica tionContextUtils;
import com.megasoft.wiradmin.delegate.ICacheDelegate;
public class AuthenticateAction extends WIRAdminBaseAction {
private static final long serialVersionUID = 1L;
public String authenticate() throws UnknownHostException, CryptoException,
DataAccessException, SQLException{
/** This way of calling works...... This is not encouraged, as we should not use applicationContext always **/
ApplicationContext applicationContext = WebApplicationContextUtils.getWebApplicationContex t(getServletRequest().getSession().getServletConte xt());
ICacheDelegate cacheAction = (ICacheDelegate) applicationContext.getBean("MNCCacheDelegate");
/** The below way of calling does NOT work .... returns null value.... Please help...
* I assume that, since I have extended the WIRAdminBaseAction, i should be able to call the getCacheDelegate directly
* and it should return my cacheDelegate object ...
* Again, Please note.....if I change my applicationContext_MNC.xml as below, the below way of calling works fine...
* but, i don't want to change my applicationContext_MNC.xml as below, due to some necessity.
*
<bean id="MNCWIRAdminBaseAction" class="com.megasoft.wiradmin.web.action.WIRAdminBaseAction">
<property name="cacheDelegate">
<ref bean="cacheDelegate" />
</property>
</bean>
*
<bean id="cacheDelegate" class="com.megasoft.wiradmin.delegate.CacheDelegate" >
<property name="statusDBDAO"><ref bean="MNCStatusDBDAO" /></property>
</bean>
*
... is it that the name and bean should have the same value.... ??? No Need to be.....Am i right ? Please advise.
*
* **/
getCacheDelegate().getActorAction(1); // this way of calling doesn't work and returns null value. please help.
return "success";
}
}
****** WIRAdminBaseAction.java ******
package com.megasoft.wiradmin.web.action;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.struts2.interceptor.ParameterAware;
import org.apache.struts2.interceptor.SessionAware;
import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.Preparable;
import com.opensymphony.xwork2.config.entities.Parameteri zable;
import com.megasoft.wiradmin.delegate.ICacheDelegate;
public class WIRAdminBaseAction extends ActionSupport implements Preparable, ParameterAware, Parameterizable, SessionAware,RequestAware {
private HttpServletRequest request;
private static final long serialVersionUID = 1L;
private HttpServletResponse response;
private ICacheDelegate cacheDelegate;
private Map session;
private Map<String, String> params;
private Map parameters;
public void prepare() throws Exception {
}
public String execute() throws Exception {
return SUCCESS;
}
public void setServletRequest(HttpServletRequest request) {
this.request = request;
}
public HttpServletRequest getServletRequest() {
return this.request;
}
public void setServletResponse(HttpServletResponse response) {
this.response = response;
}
public HttpServletResponse getServletResponse() {
return this.response;
}
public ICacheDelegate getCacheDelegate() {
return cacheDelegate;
}
public void setCacheDelegate(ICacheDelegate cacheDelegate) {
this.cacheDelegate = cacheDelegate;
}
public void addParam(final String key, final String value) {
this.params.put(key, value);
}
public Map getParams() {
return params;
}
public void setParams(final Map<String, String> params) {
this.params = params;
}
public Map getSession() {
return this.session;
}
public void setSession(final Map session) {
this.session = session;
}
public void setParameters(final Map param) {
this.parameters = param;
}
}
PreXMLWebApplicationContext.java **
package com.megasoft.wiradmin.util;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.web.context.support.XmlWebApplicationContext;
public class PreXMLWebApplicationContext extends XmlWebApplicationContext {
/**
* This initializes the Logger.
*/
private static Log logger = LogFactory.getLog(PreXMLWebApplicationContext.class);
protected String[] getDefaultConfigLocations() {
String environment = System.getProperty("envProperty");
String webirConfig = System.getProperty("webirConfig");
String fi = System.getProperty("FI");
String preHostConfiguration =null;
logger.info("The environment is "+environment);
logger.info("The webirConfig is "+webirConfig);
logger.info("The fi is "+fi);
if(environment != null && webirConfig != null && fi != null) {
preHostConfiguration = DEFAULT_CONFIG_LOCATION_PREFIX +
"classes/applicationContext" + "_" + fi.toUpperCase() +
DEFAULT_CONFIG_LOCATION_SUFFIX;
}
return new String[]{DEFAULT_CONFIG_LOCATION, preHostConfiguration};
}
/**
* This is close API.
*
* #see org.springframework.context.support.AbstractApplicationContext
* #close()
*/
public void close() {
this.doClose();
logger.info("Login-->into the closed");
}
}
<property name="userDelegate" ref="userDelegate" />
name is the field name in your class. When name is userDelegate, it means that WIRAdminBaseAction has a field named userDelegate (and probably a setter setUserDelegate())
ref is the bean name you want to set this field to. In your example, you should have another bean, named userDelegate or bmoUserDelegate which should be set as userDelegate in WIRAdminBaseAction.
So if you want to use the second configuration:
You just need to create a bean with id bmoUserDelegate:
<bean id="bmoUserDelegate" class="mypackage.BmoUserDelegateClass"/>
I am doing sample chat application using spring mvc and redis server by following steps from
http://blog.springsource.org/2012/05/16/spring-mvc-3-2-preview-chat-sample/
the example given there is by spring java based configurations. I want to do with xml based configurations. But it is not working for me.
I am getting the issues by converting following configuration class
package org.springframework.samples.async.config;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.core.env.Environment;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.listener.PatternTopic;
import org.springframework.data.redis.listener.RedisMessageListenerContainer;
import org.springframework.samples.async.chat.ChatController;
#Configuration
#PropertySource("classpath:redis.properties")
public class RootConfig {
#Autowired
Environment env;
#Autowired
ChatController chatController;
#Bean
public RedisConnectionFactory redisConnectionFactory() {
JedisConnectionFactory cf = new JedisConnectionFactory();
cf.setHostName(this.env.getProperty("redis.host"));
cf.setPort(this.env.getProperty("redis.port", int.class));
cf.setPassword(this.env.getProperty("redis.password"));
return cf;
}
#Bean
public StringRedisTemplate redisTemplate() {
return new StringRedisTemplate(redisConnectionFactory());
}
#Bean
public RedisMessageListenerContainer redisMessageListenerContainer() {
RedisMessageListenerContainer mlc = new RedisMessageListenerContainer();
mlc.setConnectionFactory(redisConnectionFactory());
mlc.addMessageListener(this.chatController , new PatternTopic("chat"));
return mlc;
}
}
The following is the Xml based configuration i am trying to use instead of above java based configuration.
<bean id="redisConnectionFactory" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory"
p:host-name="localhost" p:port="9994" p:password=""/>
<bean id="messageListener" class="org.springframework.data.redis.listener.adapter.MessageListenerAdapter">
<constructor-arg>
<bean class="org.springframework.samples.async.chat.ChatController"/>
</constructor-arg>
</bean>
<bean id="redisMessageListenerContainer" class="org.springframework.data.redis.listener.RedisMessageListenerContainer">
<property name="connectionFactory" ref="redisConnectionFactory"/>
<property name="messageListeners">s
<map>
<entry key-ref="messageListener">
<bean class="org.springframework.data.redis.listener.PatternTopic">
<constructor-arg value="chat"/>
</bean>
</entry>
</map>
</property>
</bean>
The exception i am getting is
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'messageListener' defined in ServletContext resource [/WEB-INF/spring/mvc-config.xml]: Cannot create inner bean 'org.springframework.samples.async.chat.ChatController#74b70648' of type [org.springframework.samples.async.chat.ChatController] while setting constructor argument; nested exception is org.springframework.beans.factory.CannotLoadBeanClassException: Cannot find class [org.springframework.samples.async.chat.ChatController] for bean with name 'org.springframework.samples.async.chat.ChatController#74b70648' defined in ServletContext resource [/WEB-INF/spring/mvc-config.xml]; nested exception is java.lang.ClassNotFoundException: org.springframework.samples.async.chat.ChatController
at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveInnerBean(BeanDefinitionValueResolver.java:282)
at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveValueIfNecessary(BeanDefinitionValueResolver.java:121)
at org.springframework.beans.factory.support.ConstructorResolver.resolveConstructorArguments(ConstructorResolver.java:629)
at org.springframework.beans.factory.support.ConstructorResolver.autowireConstructor(ConstructorResolver.java:148)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireConstructor(AbstractAutowireCapableBeanFactory.java:1049)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:953)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:490)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:461)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:295)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:223)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:292)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:194)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:626)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:932)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:479)
at org.springframework.web.servlet.FrameworkServlet.configureAndRefreshWebApplicationContext(FrameworkServlet.java:652)
at org.springframework.web.servlet.FrameworkServlet.createWebApplicationContext(FrameworkServlet.java:600)
at org.springframework.web.servlet.FrameworkServlet.createWebApplicationContext(FrameworkServlet.java:666)
at org.springframework.web.servlet.FrameworkServlet.initWebApplicationContext(FrameworkServlet.java:519)
at org.springframework.web.servlet.FrameworkServlet.initServletBean(FrameworkServlet.java:460)
at org.springframework.web.servlet.HttpServletBean.init(HttpServletBean.java:136)
at javax.servlet.GenericServlet.init(GenericServlet.java:160)
at org.apache.catalina.core.StandardWrapper.initServlet(StandardWrapper.java:1280)
at org.apache.catalina.core.StandardWrapper.loadServlet(StandardWrapper.java:1193)
at org.apache.catalina.core.StandardWrapper.allocate(StandardWrapper.java:865)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:136)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:123)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:472)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:171)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:99)
at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:936)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:407)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1004)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:589)
at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:310)
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
at jav
a.lang.Thread.run(Thread.java:662)
ChatController.java
package org.springframework.samples.async.chat;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.ConcurrentHashMap;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.connection.Message;
import org.springframework.data.redis.connection.MessageListener;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.context.request.async.DeferredResult;
#Controller
#RequestMapping("/mvc/chat")
public class ChatController implements MessageListener {
private final Map<DeferredResult<List<String>>, Integer> chatRequests =
new ConcurrentHashMap<DeferredResult<List<String>>, Integer>();
private final ChatRepository chatRepository;
#Autowired
public ChatController(ChatRepository chatRepository) {
this.chatRepository = chatRepository;
}
#RequestMapping(method=RequestMethod.GET, produces="application/json")
#ResponseBody
public DeferredResult<List<String>> getMessages(#RequestParam int messageIndex) {
final DeferredResult<List<String>> deferredResult = new DeferredResult<List<String>>(null, Collections.emptyList());
this.chatRequests.put(deferredResult, messageIndex);
deferredResult.onCompletion(new Runnable() {
#Override
public void run() {
chatRequests.remove(deferredResult);
}
});
List<String> messages = this.chatRepository.getMessages(messageIndex);
if (!messages.isEmpty()) {
deferredResult.setResult(messages);
}
return deferredResult;
}
#RequestMapping(method=RequestMethod.POST)
#ResponseBody
public void postMessage(#RequestParam String message) {
this.chatRepository.addMessage(message);
}
// Redis MessageListener contract
#Override
public void onMessage(Message message, byte[] pattern) {
for (Entry<DeferredResult<List<String>>, Integer> entry : this.chatRequests.entrySet()) {
List<String> messages = this.chatRepository.getMessages(entry.getValue());
entry.getKey().setResult(messages);
}
}
}
The complete mvc-config.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd">
<mvc:annotation-driven>
<mvc:async-support default-timeout="30000" />
</mvc:annotation-driven>
<mvc:view-controller path="/" view-name="chat"/>
<mvc:resources mapping="/resources/**" location="resources"/>
<context:component-scan base-package="org.springframework.samples.async.chat" />
<bean id="templateResolver" class="org.thymeleaf.templateresolver.ServletContextTemplateResolver">
<property name="prefix" value="/WEB-INF/templates/" />
<property name="suffix" value=".html" />
<property name="templateMode" value="HTML5" />
<property name="cacheable" value="true" />
</bean>
<bean id="templateEngine" class="org.thymeleaf.spring3.SpringTemplateEngine">
<property name="templateResolver" ref="templateResolver" />
</bean>
<bean id="viewResolver" class="org.thymeleaf.spring3.view.ThymeleafViewResolver">
<property name="templateEngine" ref="templateEngine" />
<property name="order" value="1" />
<property name="viewNames" value="*.html"/>
</bean>
<bean id="stringRedisTemplate" class="org.springframework.data.redis.core.StringRedisTemplate"
p:connection-factory-ref="redisConnectionFactory"/>
<bean id="redisConnectionFactory" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory"
p:host-name="localhost" p:port="9994" p:password=""/>
<bean id="messageListener" class="org.springframework.data.redis.listener.adapter.MessageListenerAdapter">
<constructor-arg>
<bean class="org.springframework.samples.async.chat.ChatController"/>
</constructor-arg>
</bean>
<bean id="redisMessageListenerContainer" class="org.springframework.data.redis.listener.RedisMessageListenerContainer">
<property name="connectionFactory" ref="redisConnectionFactory"/>
<property name="messageListeners">
<!-- map of listeners and their associated topics (channels or/and patterns) -->
<map>
<entry key-ref="messageListener">
<bean class="org.springframework.data.redis.listener.PatternTopic">
<constructor-arg value="chat"/>
</bean>
</entry>
</map>
</property>
</bean>
</beans>
Please help me out.
I think the issue is that you are trying to do some sort of autowire by class thing in your xml with this portion (I am assuming):
<bean id="messageListener" class="org.springframework.data.redis.listener.adapter.MessageListenerAdapter">
<constructor-arg>
<bean class="org.springframework.samples.async.chat.ChatController"/>
</constructor-arg>
</bean>
But that is not how the xml configuration works. What the xml is doing here is trying to create a new instance of the ChatController and use it as a constructor argument to the MessageListenerAdapter. Obviously this doesn't work because your ChatController has no 0 arg constructors. What you want to do instead is reference your existing ChatController (which is marked as an #Controller and will therefore be automatically picked up by your component-scan) in the constructor argument. Something like this:
<bean id="messageListener" class="org.springframework.data.redis.listener.adapter.MessageListenerAdapter">
<constructor-arg>
<ref bean="chatController"/>
</constructor-arg>
</bean>
The bean being referenced by 'chatController' is your component-scanned ChatController (it is the default bean name when none is provided via the stereotype annotations or the #Qualifier annotation).