Hibernate SaveOrUpdate doing nothing - spring

I work with Spring 3.2 and Hibernate 3.6.7.
I have a form that display an entity, the form is submited and the entity is saved. Using the saveOrUpdate method.
It worked until I made my entity class implements FieldHandled.
Now saveOrUpdate() does nothing.
I read the Hibernate source code and it says (shortcut) that if the Entity implements FieldHandled and if the FieldHandler is not dirty then does nothing.
here is my code :
#Controller
#Transactional
public class CustomerContactController {
....
#ModelAttribute
public CustomerContactAddressDTO getCustomerContactAddress(final HttpServletRequest request) {
CustomerContactAddressDTO customerContactAddressDTO = new CustomerContactAddressDTO();
customerAddress = customerAddressDao.findById(customerAddressUid);
customerContactAddressDTO.setCustomerContact(customerAddress.getCustomerContact());
return customerContactAddressDTO;
}
#Secured(UserService.ROLE_PREFIX + "right.customer.contact.update")
#RequestMapping(value = "/customer/contact/formedit/{customerContactAddressDTOUid}", method = RequestMethod.POST)
public #ResponseBody
ReturnFormResult formEditSubmit(#ModelAttribute CustomerContactAddressDTO customerContactAddressDTO,
#PathVariable final String customerContactAddressDTOUid) {
final CustomerAddress customerAddress = customerContactAddressDTO.getCustomerAddress();
ReturnFormResult rfr = new ReturnFormResult();
rfr.setMode("update");
rfr.setStatus(Boolean.TRUE);
customerAddressDao.saveOrUpdate(customerAddress);
return rfr;
}
}
Entity :
#Entity
#Table(name = "t_customer_contact_address")
public class CustomerAddress implements FieldHandled{
#Id
#GeneratedValue(generator = "uuid")
#GenericGenerator(name = "uuid", strategy = "uuid2")
#Column(name = "customer_contact_address_uid", updatable = false)
private String id;
....
#Basic(fetch=FetchType.LAZY)
#Formula("(some native sql query)")
private String groupTransactionCodes;
private FieldHandler fieldHandler;
#Override
public void setFieldHandler(FieldHandler handler) {
this.fieldHandler = handler;
}
#Override
public FieldHandler getFieldHandler() {
return fieldHandler;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getGroupTransactionCodes() {
if(fieldHandler!=null){
return (String)fieldHandler.readObject(this, "groupTransactionCodes", groupTransactionCodes);
}
return groupTransactionCodes;
}
public void setGroupTransactionCodes(String groupTransactionCodes) {
this.groupTransactionCodes = groupTransactionCodes;
}
}
this is hibernate code source
!FieldInterceptionHelper.isInstrumented( entity ) = false because my entity is intrumented
FieldInterceptionHelper.extractFieldInterceptor( entity) return the fieldHandler of my Entity which is dirty == false
true && ( false || false || false) = false
hibernate source code :
as mightBeDirty == false for him update is notNecessary and doesn't schedule update.
My question :
How could I have make the saveOrUpdate() really update in database when I use it on detached entity wich are instrumented ?
Thanks
database configuration :
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
<property name="packagesToScan" value="com.XXXX.db.pojo"/>
<property name="dataSource" ref="dataSource" />
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">com.XXXX.application.utils.MSSQLAHEADDialect</prop>
<prop key="hibernate.cache.region.factory_class">net.sf.ehcache.hibernate.EhCacheRegionFactory</prop>
<prop key="hibernate.jdbc.batch_size">20</prop>
<prop key="hibernate.format_sql">false</prop>
<prop key="hibernate.show_sql">true</prop>
<prop key="hibernate.use_sql_comments">false</prop>
<prop key="hibernate.hbm2ddl.auto">validate</prop>
<prop key="hibernate.cache.use_second_level_cache">true</prop>
<prop key="hibernate.cache.use_query_cache">true</prop>
<prop key="hibernate.generate_statistics">true</prop>
</props>
</property>
<property name="eventListeners">
<map>
<entry key="save-update" value-ref="saveEventListener" />
<entry key="flush-entity" value-ref="flushEntityEventListener" />
<entry key="post-load" value-ref="postLoadEventListener" />
</map>
</property>
</bean>
<bean id="saveEventListener" parent="callbackHandlerEventListener" class="org.hibernate.ejb.event.EJB3SaveOrUpdateEventListener" />
<bean id="flushEntityEventListener" parent="callbackHandlerEventListener" class="org.hibernate.ejb.event.EJB3FlushEntityEventListener" />
<bean id="postLoadEventListener" parent="callbackHandlerEventListener" class="org.hibernate.ejb.event.EJB3PostLoadEventListener" />
<bean id="entityCallbackHandler" class="org.hibernate.ejb.event.EntityCallbackHandler" />
<bean id="callbackHandlerEventListener" abstract="true" class="org.hibernate.ejb.event.CallbackHandlerConsumer">
<property name="callbackHandler" ref="entityCallbackHandler" />
</bean>
<bean id="dataSource" class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName" value="java:comp/env/jdbc/dataSourceAHEAD"/>
</bean>

I hacked by just doing this before saving :
customerAddress.getFieldHandler().writeObject(customerAddress, "name", customerAddress.getName(), customerAddress.getName());
it will force dirty to becode true.
I feel like when a Entity implements FieldHandled, It prevent any kind of automatic runtime instrumentation.I think I should implement all the setter by hand like this :
public void setXXX(String xxx) {
getFieldHandler().writeObject(this, "xxx", this.xxx, xxx);
this.xxx = xxx;
}
calling writeObject by hand in each setter.

Related

Failed to convert value of type 'java.lang.String' to required type 'int'; For input string: "save"

**Resolving exception from handler [com.controller.EmpController#77cb027f]: org.springframework.beans.TypeMismatchException: Failed to convert value of type 'java.lang.String' to required type 'int'; nested exception is java.lang.NumberFormatException: For input string: "save"
**
this is the controller part
#Controller
public class EmpController {
private static final Logger logger = Logger
.getLogger(EmpController.class);
public EmpController() {
System.out.println("EmpController()");
}
#Autowired
private EmpService service;
#Autowired
private UserService userservice;
public UserService getUserservice() {
return userservice;
}
public void setUserservice(UserService userservice) {
this.userservice = userservice;
}
public EmpService getService() {
return service;
}
public void setService(EmpService service) {
this.service = service;
}
#RequestMapping(value="login", method= RequestMethod.GET)
public ModelAndView showlogin(HttpServletRequest request, HttpServletResponse response) {
ModelAndView mav= new ModelAndView("login");
mav.addObject("login", new User() );
return mav;
}
#RequestMapping(value="loginProcess", method= RequestMethod.POST)
public ModelAndView loginProcess(HttpServletRequest request, HttpServletResponse response,
Model model,#ModelAttribute("login") User user) {
ModelAndView mav = null;
boolean user1 = userservice.validateUser(user);
if(false != user1) {
List<Emp> list = service.getAllEmployees();
model.addAttribute("list", list);
mav= new ModelAndView("empform","command",new Emp());
mav.addObject("userId", user.getUserId());
} else {
mav= new ModelAndView("login");
mav.addObject("message","UserId and Password is wrong");
}
return mav;
}
#RequestMapping(value="/empform", method= RequestMethod.GET)
public ModelAndView showform(Model model,#ModelAttribute("emp") Emp emp) throws IOException {
System.out.println(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>");
List<Emp> list = service.getAllEmployees();
model.addAttribute("list", list);
return new ModelAndView("empform","command",new Emp());
}
/* #RequestMapping(value="/newEmp", method= RequestMethod.GET)
public ModelAndView newContact(ModelAndView model) {
Emp emp = new Emp();
model.addObject("emp", emp);
model.setViewName("empform");
return model;
} */
#RequestMapping(value = "/save", method = RequestMethod.POST)
public ModelAndView saveEmployee(#ModelAttribute Emp emp,Model model) {
System.out.println(">>>>welcome to save>>>>>");
if (emp.getEmpId() == 0) {
service.save(emp);
} else {
service.update(emp);
}
List<Emp> list = service.getAllEmployees();
model.addAttribute("list", list);
return new ModelAndView("redirect:/empform");
}
#RequestMapping(value="/delete/{empId}", method= RequestMethod.GET)
public ModelAndView delete(Model model,#PathVariable int empId) {
service.delete(empId);
List<Emp> list = service.getAllEmployees();
model.addAttribute("list", list);
return new ModelAndView("redirect:/empform");
}
#RequestMapping(value="/edit/{empId}")
public ModelAndView edit(Model model,#PathVariable int empId) {
System.out.println(">>>>>>>>>>>edit");
Emp emp= service.getEmpById(empId);
System.out.println(">>>>>>>>> continue edit>>>>");
return new ModelAndView("empform","command", emp);
}
}
this is the spring-srvlet.xml
<context:component-scan base-package="com.controller">
</context:component-scan>
<bean
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/"></property>
<property name="suffix" value=".jsp"></property>
</bean>
<bean id="dataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver">
</property>
<property name="url" value="jdbc:mysql://10.125.129.252:3306/nehaempdb">
</property>
<property name="username" value="root"></property>
<property name="password" value="admin"></property>
</bean>
<bean id="sessionFactory"
class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource"></property>
<property name="hibernateProperties">
<props>
<prop
key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
<prop key="hibernate.hbm2ddl.auto">update</prop>
<prop key="hibernate.format_sql">true</prop>
<prop key="hibernate.show_sql">true</prop>
</props>
</property>
<property name="packagesToScan" value="com.model"></property>
</bean>
<bean id="service" class="com.service.EmpService">
</bean>
<bean id="userservice" class="com.service.UserService">
</bean>
<bean id="dao" class="com.dao.EmpDao">
</bean>
<bean id="userdao" class="com.dao.UserDao">
</bean>
<!-- Transaction -->
<bean id="transactionManager"
class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
<tx:annotation-driven transaction-manager="transactionManager" />
this is .jsp
<div align="center">
<h1>New/Edit Employee</h1>
<form:form action="save" method="post" >
<table>
<form:hidden path="empId"/>
<tr>
<td>Name:</td>
<td><form:input path="empName" /></td>
</tr>
<tr>
<td>Salary:</td>
<td><form:input path="salary" /></td>
</tr>
<tr>
<td>DeptId:</td>
<td><form:input path="deptId" /></td>
</tr>
<tr>
<td colspan="2" align="center"><input type="submit" value="Save"></td>
</tr>
</table>
</form:form>
</div>
value="Save"></td>
</tr>
</table>
</form:form>
</div>
It sounds to me like you probably have a #RequestMapping to a resource something like "/{id}" and when you are trying to hit your "/save" resource instead of mapping it to your controller method you showed in your question it is trying to parse the word "save" as an integer id for the resource "/{id}".
To fix this you should rename this previous resource mapping from "/{id}" to something with a suitable prefix "/something/{id}.
I had this same problem and Plog is correct about having a numeric route map.
However, instead of changing "/{id}" to "/something/{id}", you can change it "/{id:\\d+}" and then it won't match "/save".
I use the numeric regex for all "/id" cases so that I don't have this problem. For example "/users/25" and "/users/forgotpassword".
I had the same problem, but the solution for me was simple:
In the following code I forgot the first / in / admin / products when I was updating the history with history.push ('/ admin / products');
My code:
useEffect(() => {
if (isEditing) {
makeRequest({ url: `/products/${productId}` })
.then(response => {
setValue('name', response.data.name);
setValue('price', response.data.price);
setValue('description', response.data.description);
setValue('imgUrl', response.data.imgUrl);
})
}
}, [productId, isEditing, setValue]);
const onSubmit = (data: FormState) => {
makePrivateRequest({
url: isEditing ? `/products/${productId}` : '/products',
method: isEditing ? 'PUT' : 'POST',
data
})
.then(() => {
toast.info('Produto salvo com sucesso!');
history.push('/admin/products');
})
.catch(() => {
toast.error('Erro ao salvar produto!');
})
}

Batch insertion with Spring MVC and Hibernate 3

I am using Spring MVC + Hibernate and try to save bulk record using "hibernate batch procession technique" but getting below exception when I am doing session.flush() and session.clear().
org.hibernate.LazyInitializationException: could not initialize proxy - no Session
following is my code sample
DaoImpl method
#SuppressWarnings("unchecked")
#Override
public String transferPsalesDataToMisSales() {
Session session = null;
Transaction tx=null;
String result="failed";
try {session = this.getSessionFactory().openSession();
tx = session.beginTransaction();
Criteria criteria=session.createCriteria(PsalesInfo.class);
List<PsalesInfo> pSalesData=criteria.list();
if(pSalesData.size() >0){
Iterator<PsalesInfo> it=pSalesData.iterator();
int index=0;
MisSalesInfo mis=null;
while(it.hasNext()){
mis=new MisSalesInfo();
PsalesInfo psales=it.next();
StockistInfo stockistInfo=psales.getStockistInfo();
TalukaInfo talukaInfo=stockistInfo.getTalukaInfo();
IsrInfo isr=(IsrInfo) session.get(IsrInfo.class, stockistInfo.getIsrId());
//mis settters
mis.setMisSalesId(psales.getPsalesId());
mis.setStateName(talukaInfo.getDistrictInfo().getStateInfo().getStateName());
mis.setDistName(talukaInfo.getDistrictInfo().getDistName());
mis.setTalukaName(talukaInfo.getTalukaName());
mis.setAsmId(talukaInfo.getAsmInfo().getAsmId());
mis.setTsoId(stockistInfo.getTsoInfo().getTsoId());
if(null!=isr){
mis.setIsrId(isr.getIsrId());
mis.setIsrName(isr.getIsrName());
}
mis.setUnitNo(stockistInfo.getUnitNo());
mis.setBillNo(psales.getBillNo());
session.save(mis);
if(index % 50==0){
//flush a batch of inserts and release memory:
session.flush();
session.clear();
}
index++;
}//end of while
tx.commit();
result=pSalesData.size()+" Psales are Successfully transfered to MIS Sales";
}
else{
result="No Psales is available to transfer since are already available in MIS Sales";
}
} catch (HibernateException e) {
tx.rollback();
logger.error("error in MasterDaoImpl transfer data:"+e);
}finally {
if (null != session)
session.close();
}
return result;
}
POJOs
#Entity
#Table(name = "psales_info", catalog = "secondary_sales")
public class PsalesInfo implements java.io.Serializable {
private static final long serialVersionUID = 5578632011679493005L;
private Integer psalesId;
private StockistInfo stockistInfo;
//and some other attributes
//getter and setters
#Id
#GenericGenerator(name="generator", strategy="increment")
#GeneratedValue(generator="generator")
#Column(name = "psales_id", unique = true, nullable = false)
public Integer getPsalesId() {
return this.psalesId;
}
public void setPsalesId(Integer psalesId) {
this.psalesId = psalesId;
}
#ManyToOne(fetch = FetchType.LAZY)
#JoinColumn(name = "pcode", nullable = false)
public StockistInfo getStockistInfo() {
return this.stockistInfo;
}
//and others
#Entity
#Table(name = "stockist_info", catalog = "secondary_sales")
public class StockistInfo implements java.io.Serializable {
private String stockistId;
private TalukaInfo talukaInfo;
//and rest attributes
//getters and setters
// Property accessors
#Id
#Column(name = "stockist_id", unique = true, nullable = false, length = 10)
public String getStockistId() {
return this.stockistId;
}
public void setStockistId(String stockistId) {
this.stockistId = stockistId;
}
#ManyToOne(fetch = FetchType.LAZY)
#JoinColumn(name = "taluka_sid", nullable = false)
public TalukaInfo getTalukaInfo() {
return this.talukaInfo;
}
ServiceImpl
#Service
#Transactional
public class TransactionServiceImpl implements TransactionService {
#Autowired
private TransactionDAO transactionDAO;
#Override
public String transferPsalesDataToMisSales() {
return this.getTransactionDAO().transferPsalesDataToMisSales();
}
}
dispature-servlet.xml
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource"></property>
<property name="configLocation" value="classpath:hibernate.cfg.xml"/>
<property name="configurationClass" value="org.hibernate.cfg.AnnotationConfiguration"/>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">${hibernate.dialect}</prop>
<prop key="hibernate.show_sql">${hibernate.show_sql}</prop>
<prop key="hibernate.hbm2ddl.auto">${hibernate.hbm2ddl.auto}</prop>
<prop key="hibernate.default_catalog">${hibernate.default_catalog}</prop>
<prop key="hibernate.jdbc.batch_size">50</prop>
</props>
</property>
</bean>
<tx:annotation-driven transaction-manager="transactionManager"/>
<bean id="transactionManager"
class="org.springframework.orm.hibernate3.HibernateTransactionManager"
p:sessionFactory-ref="sessionFactory"/>
Need help here why it is throwing LazyInitializationException when I'm clearing the session.
But when I'm not clearing the session ie. wihtout session.clear() and session.flush() application is running properly.
but I know it may lead to OutOfMemoryException in case of more bulk record.
so plz tell how to deal with this situation now?
Your dao code is flawed... Don't open new sessions yourself and don't mess aroudn with transactions yourself either. Remove the transaction stuff from your dao method and the call to openSession should be replaced with getCurrentSession.
#SuppressWarnings("unchecked")
#Override
public String transferPsalesDataToMisSales() {
Session session = this.getSessionFactory().getCurrentSession();
Criteria criteria=session.createCriteria(PsalesInfo.class);
List<PsalesInfo> pSalesData=criteria.list();
int index=0;
for (PsalesInfo psales : pSalesData) {
MisSalesInfo mis=new MisSalesInfo();
StockistInfo stockistInfo=psales.getStockistInfo();
TalukaInfo talukaInfo=stockistInfo.getTalukaInfo();
IsrInfo isr=(IsrInfo) session.get(IsrInfo.class, stockistInfo.getIsrId());
//mis settters
mis.setMisSalesId(psales.getPsalesId());
mis.setStateName(talukaInfo.getDistrictInfo().getStateInfo().getStateName());
mis.setDistName(talukaInfo.getDistrictInfo().getDistName());
mis.setTalukaName(talukaInfo.getTalukaName());
mis.setAsmId(talukaInfo.getAsmInfo().getAsmId());
mis.setTsoId(stockistInfo.getTsoInfo().getTsoId());
if(null!=isr){
mis.setIsrId(isr.getIsrId());
mis.setIsrName(isr.getIsrName());
}
mis.setUnitNo(stockistInfo.getUnitNo());
mis.setBillNo(psales.getBillNo());
session.save(mis);
if(index % 50==0){
//flush a batch of inserts and release memory:
session.flush();
session.clear();
}
index++;
}//end of loop
if (pSalesData.isEmpty() ) {
return "No Psales is available to transfer since are already available in MIS Sales";
} else {
return pSalesData.size()+" Psales are Successfully transfered to MIS Sales";
}
}

String to Date Conversion in Spring 4.0

I am educating myself on Spring 4.0.0 M3
Following is the code,
Bean
package org.chebus.springs;
import java.util.Date;
public class Traingle {
private String name;
private int height;
private Date date;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getHeight() {
return height;
}
public void setHeight(int height) {
this.height = height;
}
public Date getDate() {
return date;
}
public void setDate(Date date) {
this.date = date;
}
public void drawShape() {
System.out.println(getName() + " Traingle height " + getHeight()
+ " Date = " + getDate());
}
}
Main
ApplicationContext ctx = new ClassPathXmlApplicationContext("org/chebus/springs/Spring.xml");
Traingle traingle = ctx.getBean("traingle",Traingle.class);
traingle.drawShape();
XML Config
<?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-2.5.xsd">
<bean id = "traingle" class="org.chebus.springs.Traingle">
<property name="name" value = "RightAngled"/>
<property name="height" value = "20"/>
<property name="date" value = "2013-09-10"/>
</bean>
<bean id="dateEditor"
class="org.springframework.beans.propertyeditors.CustomDateEditor">
<constructor-arg>
<bean class="java.text.SimpleDateFormat">
<constructor-arg value="yyyy-MM-dd" />
</bean>
</constructor-arg>
<constructor-arg value="true" />
</bean>
<bean class="org.springframework.beans.factory.config.CustomEditorConfigurer">
<property name="customEditors">
<map>
<entry key="java.util.Date">
<ref local="dateEditor" />
</entry>
</map>
</property>
</bean>
</beans>
Exception:
java.lang.IllegalArgumentException: Cannot convert value of type
[org.springframework.beans.propertyeditors.CustomDateEditor] to
required type [java.lang.Class] for property
'customEditors[java.util.Date]': PropertyEditor
[org.springframework.beans.propertyeditors.ClassEditor] returned
inappropriate value of type
[org.springframework.beans.propertyeditors.CustomDateEditor] at
org.springframework.beans.TypeConverterDelegate.convertIfNecessary(TypeConverterDelegate.java:260)
at
org.springframework.beans.TypeConverterDelegate.convertToTypedMap(TypeConverterDelegate.java:620)
at
org.springframework.beans.TypeConverterDelegate.convertIfNecessary(TypeConverterDelegate.java:205)
at
org.springframework.beans.BeanWrapperImpl.convertIfNecessary(BeanWrapperImpl.java:459)
... 17 more
Not sure where i am going wrong. Appreciate your help. Thanks!
Good catch, this seems to be a new behavior with Spring 4.0+, your code works cleanly with 3.2.x version of Spring.
The reason appears to be because the type of customEditors in
CustomEditorConfigurer has changed with Spring 4.0+. Whereas it was of type Map<String, ?> with Spring 3.2.x it is Map<Class<?>, Class<? extends PropertyEditor>> with Spring 4.0+.
The fix is to instead create a custom PropertyEditorRegistrar, this way:
import java.text.SimpleDateFormat;
import java.util.Date;
import org.springframework.beans.PropertyEditorRegistrar;
import org.springframework.beans.PropertyEditorRegistry;
import org.springframework.beans.propertyeditors.CustomDateEditor;
public class CustomDateEditorRegistrar implements PropertyEditorRegistrar {
#Override
public void registerCustomEditors(PropertyEditorRegistry registry) {
registry.registerCustomEditor(Date.class, new CustomDateEditor(new SimpleDateFormat("yyyy-MM-dd"), false));
}
}
and to use this in the configuration:
<bean class="org.springframework.beans.factory.config.CustomEditorConfigurer">
<property name="propertyEditorRegistrars">
<list>
<bean class="dateeditor.CustomDateEditorRegistrar"/>
</list>
</property>
</bean>
There is no builtin of Date values by default in spring.
Here you go :
How to initialize a Java Date object in Spring xml configuration file?

Initialising static list using spring

I have a class as below:
public class SensitivityDescription {
private final String measureId;
private final ColumnType type; private final String sensName;
private final SensType sensType;
private final ServicePhase svcPhase;
private final AggregateFunction agFn;
private final String positionEnum;
private static List <SensitivityDescription> senRecordList = new ArrayList<SensitivityDescription> ();
public SensitivityDescription(String measureId, ColumnType type,
String sensName, SensType sensType, ServicePhase svcPhase,
AggregateFunction agFn, String positionEnum) {
super();
this.measureId = measureId;
this.type = type;
this.sensName = sensName;
this.sensType = sensType;
this.svcPhase = svcPhase;
this.agFn = agFn;
this.positionEnum = positionEnum;
}
I need to populate the static senRecordList with objects of the SensitivityDescription class.How do I do this in spring xml.
Based on this link everything is working:
Class
package com.sopovs.moradanen.test;
import java.util.List;
public class SensitivityDescription {
private String name;
private static List<SensitivityDescription> senRecordList;
public SensitivityDescription(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public static void setSenRecordList(List<SensitivityDescription> senRecordList) {
SensitivityDescription.senRecordList = senRecordList;
}
public static List<SensitivityDescription> getSenRecordList() {
return senRecordList;
}
}
Xml config:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context" xmlns:p="http://www.springframework.org/schema/p"
xmlns:c="http://www.springframework.org/schema/c" 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/context http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd">
<bean id="first" class="com.sopovs.moradanen.test.SensitivityDescription">
<constructor-arg name="name" value="first" />
</bean>
<bean id="second" class="com.sopovs.moradanen.test.SensitivityDescription">
<constructor-arg name="name" value="second" />
</bean>
<bean id="third" class="com.sopovs.moradanen.test.SensitivityDescription">
<constructor-arg name="name" value="third" />
</bean>
<bean
class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
<property name="staticMethod"
value="com.sopovs.moradanen.test.SensitivityDescription.setSenRecordList" />
<property name="arguments">
<list>
<ref bean="first" />
<ref bean="second" />
<ref bean="third" />
</list>
</property>
</bean>
</beans>
And test:
package com.sopovs.moradanen.test;
import static org.junit.Assert.assertEquals;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
#RunWith(SpringJUnit4ClassRunner.class)
#ContextConfiguration("classpath:test.xml")
public class SpringTest {
#Test
public void test() {
assertEquals(3, SensitivityDescription.getSenRecordList().size());
}
}
Spring way of thinking does not play well with your approach.
But you can work around this.
Add a public setter for senRecordList for SensitivityDescription.
Add default constructor
public class SensitivityDescription {
private final String measureId;
...
private static List <SensitivityDescription> senRecordList = new ArrayList<SensitivityDescription> ();
public SensitivityDescription(String measureId,..) {
...
}
/** new code */
public SensitivityDescription() {super();}
public void setSenRecordList(List<SensitivityDescription> senRecordList) {
SensitivityDescription.senRecordList = senRecordList;
}
}
Instance the bean once, that way the list will be injected to your field.
<bean class="...SensitivityDescription">
<property name="senRecordList">
<util:list value-type="...SensitivityDescription">
<bean class="...SensitivityDescription">
<constructor-arg name="name" “measureId”
<value>id1</value>
</constructor-arg>
<constructor-arg name="name" "sensName"
<value>name1</value>
</constructor-arg>
...
</bean>
<bean class="...SensitivityDescription">
<constructor-arg name="name" "measureId"
<value>id2</value>
</constructor-arg>
<constructor-arg name="name" "sensName"
<value>name2</value>
</constructor-arg>
...
</bean>
</util:list>
</property>
</bean>
If this is not a legacy code and you can change it, I suggest defining a singleton for those values and not a static field. Spring will like it better.

Sql is required error Spring StoredProcedure

I am getting property "sql" is required error when i execute below code. can someone help me? i dont know how do i inject Datasource in TestDAO calss so that it works properly.
public class TestDAO extends BaseStoredProcedure
{
final protected Logger logger = Logger.getLogger(this.getClass().getName());
private static final String SPROC_NAME = "dbo.SP1";
#Autowired
private JdbcTemplate jdbcTemplate;
public java.util.ArrayList<IssuerProductResponse> validIssuersProducts(java.util.ArrayList<IssuerProductRequest> issuersProducts)
{
//PARAM MAP set here
//compile SP
HIOSBaseStoredProcedure hiosBaseSP = new HIOSBaseStoredProcedure(jdbcTemplate.getDataSource(),SPROC_NAME,inMap,null,null,null);
//now set parameters
Map<String, Object> result = super.execute(parameters);
System.out.println(result);
return liReponse;
}
}
BaseStoreProcedure class
public class BaseStoredProcedure extends StoredProcedure {
public BaseStoredProcedure() {
super();
// TODO Auto-generated constructor stub
}
/**
*
* #param ds
* #param spname
* #param map
* #param sqlOutKey
* #param returnType
* #param rowmapper
*/
public BaseStoredProcedure (DataSource ds, String spname,
Map<String, Integer> map, String sqlOutKey, Integer returnType,
RowMapper rowmapper) {
super();
setDataSource(ds);
/* resultset has to be declared first over other declare parameters */
if (rowmapper != null) {
declareParameter(new SqlReturnResultSet(sqlOutKey, rowmapper));
}
if (map != null) {
Iterator itr = map.keySet().iterator();
while (itr.hasNext()) {
String key = (String) itr.next();
Integer value = (Integer) map.get(key);
declareParameter(new SqlParameter(key, value.intValue()));
}
}
/*
* sql out paramter has to be declared based on the order in stored
* procedures, In all our stored procedures we have it after input
* parameters
*/
if (returnType != null) {
declareParameter(new SqlOutParameter(sqlOutKey, returnType
.intValue()));
}
setSql(spname);
compile();
}
}
Spring configuration
<bean id="dao" class="test.dao.TestDAO"> <property name="jdbcTemplate" ref="jdbcTemplate"></property> </bean>
<bean id="baseSP" class="test.dao.BaseStoredProcedure"> </bean>
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="dataSource"/>
</bean>
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="com.microsoft.sqlserver.jdbc.SQLServerDriver" /> <property name="url" value="jdbc:sqlserver://IP:1433;databaseName=DB;" /> <property name="username" value="username" /> <property name="password" value="password" /> <property name="validationQuery" value="SELECT 1" /> <property name="initialSize" value="1"/> <property name="maxActive" value="20"/> </bean>

Resources