i had earlier created the spring framework, then replaced with the database connection, but there is problem in creating the beans.
also receiving the below error during the deployment.
DEFAULT=C:\Users\gopc\Documents\NetBeansProjects\HelloSpringJDBC\build\web&name=HelloSpringJDBC&contextroot=/HelloSpringJDBC&force=true
failed on GlassFish Server 3.1.2 Error occurred during deployment:
Exception while loading the app : java.lang.IllegalStateException:
ContainerBase.addChild: start: org.apache.catalina.LifecycleException:
org.springframework.beans.factory.BeanCreationException: Error
creating bean with name 'productManager' defined in ServletContext
resource [/WEB-INF/applicationContext.xml]: Error setting property
values; nested exception is
org.springframework.beans.NotWritablePropertyException: Invalid
property 'productDao' of bean class [SimpleProductManager]: Bean
property 'productDao' is not writable or has an invalid setter method.
Does the parameter type of the setter match the return type of the
getter?. Please see server.log for more details.
C:\Users\gopc\Documents\NetBeansProjects\HelloSpringJDBC\nbproject\build-impl.xml:1029:
The module has not been deployed. See the server log for details.
Source
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:p="http://www.springframework.org/schema/p"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd">
<bean id="externalDataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource" scope="singleton" destroy-method="close">
<property name="driverClassName" value="sun.jdbc.odbc.JdbcOdbcDriver"/>
<property name="url" value="jdbc:odbc:;DRIVER=Microsoft Access Driver (*.mdb, *.accdb);DBQ=C://Users//gopc//Documents//odbc_sql.accdb"/>
<property name="username" value=""/>
<property name="password" value=""/>
</bean>
<bean id="productManager" class="SimpleProductManager">
<property name="productDao" ref="productDao"/>
</bean>
<bean id="productDao" class="JdbcProductDao">
<property name="dataSource" ref="externalDataSource"/>
</bean>
</beans>
spirngapp-servlet.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:p="http://www.springframework.org/schema/p"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd">
<bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource">
<property name="basename" value="messages"/>
</bean>
<bean name="/hello.htm" class="HelloController">
<property name="productManager" ref="productManager"/>
</bean>
<!-- we can prefix="/"
http://localhost:8080/HelloSpring/hello.htm
specify the path in modelview from the controller
OR
Decouple the view from the controller
prefix="/WEB-INF/jsp/"
-->
<bean id="localeResolver" class="org.springframework.web.servlet.i18n.SessionLocaleResolver">
<property name="defaultLocale" value="en_US"/>
</bean>
<bean id="viewResolver"
class="org.springframework.web.servlet.view.InternalResourceViewResolver"
p:viewClass="org.springframework.web.servlet.view.JstlView"
p:prefix="/WEB-INF/jsp/"
p:suffix=".jsp" />
</beans>
JdbcProductDao.java
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.jdbc.core.namedparam.MapSqlParameterSource;
import org.springframework.jdbc.core.simple.ParameterizedRowMapper;
import org.springframework.jdbc.core.simple.SimpleJdbcDaoSupport;
public class JdbcProductDao extends SimpleJdbcDaoSupport implements ProductDao {
protected final Log logger = LogFactory.getLog(getClass());
public List<Product> getProductList() {
logger.info("Getting products!");
List<Product> products = getSimpleJdbcTemplate().query(
"select id, description, price from products",
new ProductMapper());
return products;
}
public void saveProduct(Product prod) {
logger.info("Saving product: " + prod.getDescription());
int count = getSimpleJdbcTemplate().update(
"update products set description = :description, price = :price where id = :id",
new MapSqlParameterSource().addValue("description", prod.getDescription())
.addValue("price", prod.getPrice())
.addValue("id", prod.getId()));
logger.info("Rows affected: " + count);
}
private static class ProductMapper implements ParameterizedRowMapper<Product> {
public Product mapRow(ResultSet rs, int rowNum) throws SQLException {
Product prod = new Product();
prod.setId(rs.getInt("id"));
prod.setDescription(rs.getString("description"));
prod.setPrice(new Double(rs.getDouble("price")));
return prod;
}
}
}
SimpleProductManager.java
import java.util.List;
import java.util.ArrayList;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
public class SimpleProductManager implements ProductManager {
protected final Log logger = LogFactory.getLog(getClass());
private ProductDao productDao;
public List<Product> getProductDao() {
//throw new UnsupportedOperationException();
return productDao.getProductList();
}
public void increasePrice(int percentage) {
//throw new UnsupportedOperationException();
List <Product> products = productDao.getProductList();
for (Product product : products) {
double newPrice = product.getPrice() * (100 + percentage)/100;
product.setPrice(newPrice);
productDao.saveProduct(product);
}
}
public void setProductDao(ProductDao productDao) {
//throw new UnsupportedOperationException();
logger.info("inside the setProducts in SimpleProductManager");
this.productDao = productDao;
}
}
HelloController.java
import java.util.Date;
import java.util.Map;
import java.util.HashMap;
import org.springframework.web.servlet.mvc.Controller;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import java.io.IOException;
public class HelloController implements Controller {
private ProductManager productManager;
protected final Log logger = LogFactory.getLog(getClass());
/*
public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
logger.info("Returning hello view");
String now = ( new Date().toString());
logger.info("time now:"+ now);
//return new ModelAndView("hello");
//return new ModelAndView("WEB-INF/jsp/hello","now",now);
//decouple the view from the controller
return new ModelAndView("hello","now",now);
}
*/
//Writing some business logic in the controller
public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException
{
String now = (new java.util.Date()).toString();
logger.info("returning hello view with " + now);
Map<String, Object> myModel = new HashMap<String, Object>();
myModel.put("now", now);
myModel.put("products", this.productManager.getProductDao());
return new ModelAndView("hello", "model", myModel);
}
public void setProductManager(ProductManager productManager)
{
this.productManager = productManager;
}
}
hey the problem got resovled, after i had modified, the following..
1) applicationContext with mapping for the bean "productManager" with ref productDao.
2) ProductManager interface with new method call getProducts(), then implemenent in the SimpleProductManager and which call the ProductDao.getProducts(), where the sql query is being defined.
Related
i want to have something like a plugin system for Spring which are accessible through an REST endpoint.
So I was thinking I could simply implement a controller module as #RestController bean and add it to my beans definition.
Unfortunately I cannot figure out how to configure a #RestController and #RequestMapping using XML.
So far I think I have configured the a
This is my main class:
package me.example.app;
import org.springframework.context.ApplicationContext;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.context.annotation.*;
import java.lang.System;
import java.util.Properties;
#SpringBootApplication
#RestController
#ImportResource({"classpath:applicationContext.xml"})
public class GettingstartedApplication {
public GettingstartedApplication() {
System.out.println("INIT Application");
}
#RequestMapping("/")
String home() {
return "Hello World!";
}
public static void main(String[] args) {
ApplicationContext applicationContext = SpringApplication.run(GettingstartedApplication.class, args);
}
}
This is my resources/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:util="http://www.springframework.org/schema/util" xsi:schemaLocation="
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.xsd">
<bean id="xmlStringBean1" class="java.lang.String">
<constructor-arg value="stringBean1" />
</bean>
<bean id="xmlController" class="me.tom.app.XMLController">
<constructor-arg value="xmlControllerArg" />
</bean>
<bean id="testSimpleUrlHandlerMapping" class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
<property name="mappings">
<util:map id="emails" map-class="java.util.HashMap">
<entry key="/xml" value="xmlController"/>
</util:map>
</property>
</bean>
</beans>
This is my XMLController.java
package me.example.app;
public class XMLController{
public XMLController(String arg) {
System.out.println("INIT XMLController");
}
String home() {
return "XMLController";
}
}
I have implemented transactional rollback in the following way. This code worked well when I tried to implement the same on HSql DB and SQL Server. But the same transactional rollback is not working when implemented on MySQL DB. What could be the possible solution for rolling back the transaction in case of MySQL?
Here is my code -
xml file-> implement.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"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd ">
<!-- Initialization for data source -->
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://(mydb details)"/>
<property name="username" value="(my db username)"/>
<property name="password" value="(my db password)"/>
</bean>
<!-- Initialization for TransactionManager -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource" />
</bean>
<!-- Definition for studentJDBCTemplate bean -->
<bean id="implementOnlyTransactions" class="Transactions.implementOnlyTransactions">
<property name="dataSource" ref="dataSource" />
<property name="transactionManager" ref="transactionManager" />
</bean>
</beans>
implementOnlyTransactions.java->
package Transactions;
import java.sql.SQLException;
import javax.sql.DataSource;
import org.springframework.dao.DataAccessException;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionException;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.support.DefaultTransactionDefinition;
public class implementOnlyTransactions {
private DataSource dataSource;
private JdbcTemplate jdbcTemplateObject;
private PlatformTransactionManager transactionManager;
public void setDataSource(DataSource dataSource) throws SQLException {
this.dataSource = dataSource;
this.jdbcTemplateObject = new JdbcTemplate(dataSource);
}
public void setTransactionManager(PlatformTransactionManager transactionManager) {
this.transactionManager = transactionManager;
}
public void create(Integer id, String name) throws Exception {
TransactionDefinition def = new DefaultTransactionDefinition();
TransactionStatus status = transactionManager.getTransaction(def);
try {
String SQL1 = "insert into Student (ID,Name) values (?, ?)";
int r = jdbcTemplateObject.update(SQL1, id, name);
System.out.println("Inserted Name = " + name + ", ID = " + id);
if(r>0){
transactionManager.rollback(status);
}
transactionManager.commit(status);
} catch (DataAccessException e) {
System.out.println("Error in creating record, rolling back");
//transactionManager.rollback(status);
throw e;
}
}
}
MainClass.java -->
package Transactions;
import java.sql.SQLException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class MainClass {
public static void main(String[] args) throws Exception {
ApplicationContext context = new ClassPathXmlApplicationContext("xmlFiles/implement.xml");
implementOnlyTransactions implemt =
(implementOnlyTransactions)context.getBean("implementOnlyTransactions");
try {
implemt.create(36,"bye2");
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
I trying to apply MethodBeforeAdvice but unable to do so. I am unable to figure out what is wrong with it. Please help me with it.
//Interface
package org.mycode;
public interface IHello {
boolean authenticate(String input);
}
//Class on which advice need to be applied
package org.mycode;
public class HelloImpl implements IHello {
#Override
public boolean authenticate(String input) {
System.out.println("authecated successfully");
System.out.println(System.currentTimeMillis());
System.out.println(input);
return true;
}
}
}
//Advice class
package org.mycode;
import java.lang.reflect.Method;
import org.springframework.aop.MethodBeforeAdvice;
public class MethodAdvice1 implements MethodBeforeAdvice {
#Override
public void before(Method arg0, Object[] arg1, Object arg2) throws Throwable {
System.out.println("checking for authentication of the caller");
System.out.println(arg0.getName());
System.out.println(arg0.getDeclaringClass().getName());
System.out.println(arg1);
System.out.println("time start: " + System.currentTimeMillis());
}
}
//Client for the Adviced class
package org.mycode;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.core.io.ClassPathResource;
public class AdviceManager {
public static void main(String[] args) {
ClassPathResource cp = new ClassPathResource("org/mycode/config.xml");
BeanFactory factory = new XmlBeanFactory(cp);
HelloImpl hil = (HelloImpl) factory.getBean("myClass");
System.out.println(hil.authenticate("AdvicedMethod"));
}
}
//Config file
config.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:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd">
<bean id="advice1" class="org.mycode.MethodAdvice1"></bean>
<bean id="myClass" class="org.mycode.HelloImpl"></bean>
<bean id="aspect1"
class="org.springframework.aop.support.RegexpMethodPointcutAdvisor">
<property name="advice" ref="advice1"></property>
<property name="pattern">
<value>.*</value>
</property>
</bean>
<bean id="advicedHello" class="org.springframework.aop.framework.ProxyFactoryBean">
<property name="proxyInterfaces">
<value>org.mycode.IHello</value>
</property>
<property name="target" ref="myClass" />
<property name="interceptorNames">
<list>
<value>aspect1</value>
</list>
</property>
</bean>
</beans>
output on running
INFO: Loading XML bean definitions from class path resource [org/mycode/config.xml]
authecated successfully
1467340328875
AdvicedMethod
true
This is the applicationContext.xml file which i placed in the src/main/resources folder.
<?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:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.0.xsd">
<context:property-placeholder location="classpath:jdbc.properties"/>
<!-- Employee DB data source. -->
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"
destroy-method="close">
<property name="driverClass" value="${jdbc.driverClassName}" />
<property name="jdbcUrl" value="${jdbc.url}" />
<property name="user" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}" />
<property name="maxPoolSize" value="${jdbc.maxPoolSize}" />
<property name="minPoolSize" value="${jdbc.minPoolSize}" />
<property name="maxStatements" value="${jdbc.maxStatements}" />
<property name="testConnectionOnCheckout" value="${jdbc.testConnection}" />
</bean>
<bean id="Utilities" class="com.pooling.test.Utilities">
</bean>
<context:component-scan base-package="com.pooling.controllers">
</context:component-scan>
This is the jdbc.properties file which i placed in the src/main/resources folder.
jdbc.driverClassName=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/books
jdbc.username=root
jdbc.password=admin
jdbc.maxPoolSize=50
jdbc.minPoolSize=10
jdbc.maxStatements=10
jdbc.testConnection=true
jdbc.unreturnedConnectionTimeout=240
jdbc.debugUnreturnedConnectionStackTraces=true
This is the Utilities class that contains the logic that i wish to perform
package com.pooling.test;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import javax.sql.DataSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.stereotype.Component;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.DefaultTransactionDefinition;
import com.jolbox.bonecp.BoneCP;
public class Utilities {
private final String CLASS_NAME = "Utilities";
#Autowired
private DataSource datasource;
public String createListofCategories()
{
String METHOD_NAME = "createListofCategories()";
/*//===========================================================================
TransactionDefinition mDefinition = new DefaultTransactionDefinition();
TransactionStatus mStatus = mTransactionManager.getTransaction(mDefinition);
//=========================================================================== */
String listOfCategories = "";
String sequel = "select distinct category_id, key_desc from book_resource_view, keywords_record_table";
sequel = sequel + " where keyword_key=category_id and category_id > 1 ";
sequel = sequel + " order by key_desc";
Connection connection = null;
ResultSet results = null;
Statement state = null;
int categoryID = 0;
String categoryDesc = "";
int numRows = 0;
try
{
connection = datasource.getConnection();
state = connection.createStatement();
results = state.executeQuery(sequel);
results.last();
numRows = results.getRow();
//======================================
results.beforeFirst();
for(int i=0; results.next(); i++){
listOfCategories = listOfCategories + "<td><ul id=\"category_list\">";
for(int j=0; j<16; j++){
categoryID = results.getInt("category_id");
categoryDesc = results.getString("key_desc");
listOfCategories = listOfCategories + "<li>"+categoryDesc+"</li>";
if(!results.next()){
break;
}
}
results.previous();
listOfCategories = listOfCategories + "</ul></td>";
}
listOfCategories = "<tr>"+listOfCategories+"</tr>";
}
catch (SQLException localSQLException)
{
try
{
results.close();
state.close();
connection.close();
}
catch (SQLException localSQLException1)
{
}
}
finally
{
try {
results.close();
state.close();
connection.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
return listOfCategories;
}
This is the controller code that i wish to call from the browser.
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
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.ResponseBody;
import com.pooling.test.ConnectionManager;
import com.pooling.test.Utilities;
#Controller
public class TestController {
#RequestMapping(value="/testing",method=RequestMethod.GET)
public #ResponseBody String getCategories(){
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
Utilities utilities = (Utilities) context.getBean("Utilities");
return utilities.createListofCategories();
}
}
PROBLEM: the problem is that the pool gets initialized properly but when i keep executing the same controller request again and again the connection pool keeps on creating connections until the server gives "too many connections" error
I think the problem lies in the fact that you create a new ApplicationContext everytime the getCategories() method is called.
As #Chrylis already mentioned, you don't need to call context.getBean().
Replace the two lines from ApplicationContext to context.getBean() to #Autowired Utilities utilities. Just like you did with datasource in your Utilities class.
Here's the error I'm receiving.
Caused by: java.lang.IllegalStateException: Cannot convert value of type [code.ProductFieldSetMapper] to required type [org.springframework.batch.item.file.mapping.FieldSetMapper] for property 'FieldSetMapper': no matching editors or conversion strategy found
at org.springframework.beans.TypeConverterDelegate.convertIfNecessary(TypeConverterDelegate.java:264)
at org.springframework.beans.BeanWrapperImpl.convertIfNecessary(BeanWrapperImpl.java:450)
... 23 more
Here's my context file (FileReaderConfig.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:batch="http://www.springframework.org/schema/batch"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/batch
http://www.springframework.org/schema/batch/spring-batch.xsd">
<bean id="reader" class="org.springframework.batch.item.file.FlatFileItemReader">
<property name="resource" value="file:./output.txt" />
<property name="linesToSkip" value="1" />
<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="PRODUCT_ID,NAME,DESCRIPTION,PRICE" />
</bean>
</property>
<property name="fieldSetMapper">
<bean class="code.ProductFieldSetMapper" />
</property>
</bean>
</property>
</bean>
<job id="importProducts" xmlns="http://www.springframework.org/schema/batch">
<step id="readWriteProducts">
<tasklet>
<chunk reader="reader" writer="writer" commit-interval="100" />
</tasklet>
</step>
</job>
Here's the interface (FieldSetMapper.java)
package code;
import org.springframework.batch.item.file.transform.FieldSet;
import org.springframework.validation.BindException;
public interface FieldSetMapper<T> {
T mapFieldSet(FieldSet fieldSet) throws BindException;
}
Here's ProductFieldSetMapper.java
package code;
import org.springframework.batch.item.file.transform.FieldSet;
import org.springframework.validation.BindException;
public class ProductFieldSetMapper implements FieldSetMapper<Product> {
public Product mapFieldSet(FieldSet fieldSet) throws BindException {
// TODO Auto-generated method stub
Product product = new Product();
product.setId(fieldSet.readString("PRODUCT_ID"));
product.setName(fieldSet.readString("NAME"));
product.setDescription(fieldSet.readString("DESCRIPTION"));
product.setPrice(fieldSet.readBigDecimal("PRICE"));
return product;
}
}
And here's the class that I'm running (Runner.java)
package code;
import org.omg.PortableInterceptor.SYSTEM_EXCEPTION;
import org.springframework.batch.item.file.transform.FieldSet;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.validation.BindException;
public class Runner {
public static void main(String[] args) throws BeansException, BindException {
// TODO Auto-generated method stub
Product product;
ApplicationContext context =
new ClassPathXmlApplicationContext("FileReaderConfig.xml");
ProductFieldSetMapper obj = (ProductFieldSetMapper) context.getBean("FieldSetMapper");
product = (Product) obj.mapFieldSet((FieldSet)context.getBean("lineTokenizer"));
System.out.println(product.getDescription() + ""+product.getId()+""+product.getName());
}
}
I don't see where (or why for that matter)my code is attempting to convert a ProductFieldSetMapper into a FieldSetMapper (which is just an interface, I understand that won't work).
BTW, Product.java is a POJO with variables and their respective setters and getters.
The error was the result of me using my own interface rather than the one provided by Spring. I deleted my interface class and had ProductFieldSetMapper implement org.springframework.batch.item.file.mapping.FieldSetMapper after importing it. That solved the issue.
ProductFieldSetMapper obj =
(ProductFieldSetMapper) context.getBean("FieldSetMapper");
Should be
ProductFieldSetMapper obj =
(ProductFieldSetMapper) context.getBean("fieldSetMapper");
See your bean declaration.
<property name="fieldSetMapper">
<bean class="code.ProductFieldSetMapper" />
</property>
Here is code with some correction:
Runner.java (use DelimitedLineTokenizer class to tokenize a comma separated string into FieldSet that is further used to map it with an object (Product) via ProductFieldSetMapper class)
ApplicationContext context = new ClassPathXmlApplicationContext(
"FileReaderConfig.xml");
ProductFieldSetMapper obj = (ProductFieldSetMapper) context.getBean("fieldSetMapper");
DelimitedLineTokenizer tokenizer = (DelimitedLineTokenizer) context
.getBean("lineTokenizer");
FieldSet fieldSet = tokenizer.tokenize("1,Pepsi,Cold drinks,30");
Product product = (Product) obj.mapFieldSet(fieldSet);
System.out.println(product.getDescription() + "-" + product.getId() + "-"
+ product.getName());
Config xml file: (No need to declare any beans or jobs other than two defined below because you are not using it anywhere in you Main class)
<bean id="lineTokenizer"
class="org.springframework.batch.item.file.transform.DelimitedLineTokenizer">
<property name="names" value="PRODUCT_ID,NAME,DESCRIPTION,PRICE" />
</bean>
<bean id="fieldSetMapper" class="com.spring.batch.domain.ProductFieldSetMapper" />
ProductFieldSetMapper.java: (There is no need to define your custom FieldSetMapper)
import org.springframework.batch.item.file.transform.FieldSet;
import org.springframework.validation.BindException;
public class ProductFieldSetMapper implements org.springframework.batch.item.file.mapping.FieldSetMapper<Product> {
public Product mapFieldSet(FieldSet fieldSet) throws BindException {
Product product = new Product();
product.setId(fieldSet.readString("PRODUCT_ID"));
product.setName(fieldSet.readString("NAME"));
product.setDescription(fieldSet.readString("DESCRIPTION"));
product.setPrice(fieldSet.readBigDecimal("PRICE"));
return product;
}
}
For a detailed sample please read it HERE with extra functionality using spring batch jobs.