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>
Related
I've been trying for some couple of days now I just can't seem to figure out why my Eclipselink persistence unit does not perform write operations on my DB. We used to be running OpenJPA and everything was working fine, but with the new EclipseLink config, only thing entities are capable of doing is read data. Write operations do not occur. I'm hoping someone with a better understanding of this can help me out. Maybe I'm missing something.
This is my persistence.xml
<persistence version="2.0"
xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">
<persistence-unit name="EclipseLink-PU" transaction-type="RESOURCE_LOCAL">
<provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
<exclude-unlisted-classes>false</exclude-unlisted-classes>
<shared-cache-mode>ALL</shared-cache-mode>
<properties>
<!--
<property name="eclipselink.ddl-generation.output-mode" value="database"/>
<property name="eclipselink.target-database" value="org.eclipse.persistence.platform.database.MySQLPlatform" />
Optimization - avoid auto flush cost on query execution -->
<!-- property name="eclipselink.batch.size" value="100"/-->
<property name="javax.persistence.validation.group.pre-persist" value=""/>
<property name="javax.persistence.validation.group.pre-update" value="none"/>
<property name="eclipselink.cache.shared.default" value="false"/>
<property name="eclipselink.persistence-context.close-on-commit" value="true"/>
<property name="eclipselink.persistence-context.flush-mode" value="commit"/>
<property name="eclipselink.weaving" value="static"/>
<property name="eclipselink.logging.level" value="ALL"/>
<property name="eclipselink.logging.parameters" value="true"/>
<property name="eclipselink.logging.level.sql" value="ALL"/>
<property name="eclipselink.logging.thread" value="true"/>
<property name="eclipselink.jdbc.batch-writing" value="JDBC"/>
</properties>
</persistence-unit>
My infrastructure.xml with configs for transactionManager
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:jdbc="http://www.springframework.org/schema/jdbc"
xmlns:jee="http://www.springframework.org/schema/jee"
xsi:schemaLocation="http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-3.0.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-3.0.xsd">
<!-- Necessary to get the entity manager injected into the factory bean -->
<bean class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor" />
<!-- Define EclipseLink JPA Vendor Adapter -->
<bean id="eclipseLinkAdapter"
class="org.springframework.orm.jpa.vendor.EclipseLinkJpaVendorAdapter">
<property name="generateDdl" value="false" />
<property name="showSql" value="true" />
</bean>
<bean id="entityManagerFactory"
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"
depends-on="tenantDatabaseUpgradeService">
<property name="dataSource" ref="routingDataSource" />
<property name="persistenceUnitName" value="EclipseLink-PU" />
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.EclipseLinkJpaVendorAdapter">
<property name="generateDdl" value="false" />
<property name="showSql" value="true" />
<property name="databasePlatform" value="org.eclipse.persistence.platform.database.MySQLPlatform"/>
</bean>
</property>
<!--
<property name="loadTimeWeaver">
<bean class="org.springframework.instrument.classloading.InstrumentationLoadTimeWeaver" />
<bean class="org.springframework.instrument.classloading.tomcat.TomcatLoadTimeWeaver" />
</property>-->
</bean>
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory"/>
</bean>
<!-- Create instance of transaction template for programmatic transaction manipulation -->
<bean id="txTemplate" class="org.springframework.transaction.support.TransactionTemplate">
<property name="transactionManager" ref="transactionManager"/>
</bean>
Here I have a sample entity I want to persist
#Entity
#Table(name = "m_office", uniqueConstraints = { #UniqueConstraint(columnNames = { "name" }, name = "name_org"),
#UniqueConstraint(columnNames = { "external_id" }, name = "externalid_org") })
public class Office extends AbstractPersistableCustom implements Serializable {
#OneToMany(fetch = FetchType.LAZY)
#JoinColumn(name = "parent_id")
private List<Office> children = new LinkedList<>();
#ManyToOne(fetch = FetchType.LAZY)
#JoinColumn(name = "parent_id")
private Office parent;
#Column(name = "name", nullable = false, length = 100)
private String name;
#Column(name = "hierarchy", nullable = true, length = 50)
private String hierarchy;
#Column(name = "opening_date", nullable = false)
#Temporal(TemporalType.DATE)
private Date openingDate;
#Column(name = "external_id", length = 100)
private String externalId;
public static Office headOffice(final String name, final LocalDate openingDate, final String externalId) {
return new Office(null, name, openingDate, externalId);
}
public static Office fromJson(final Office parentOffice, final JsonCommand command) {
final String name = command.stringValueOfParameterNamed("name");
final LocalDate openingDate = command.localDateValueOfParameterNamed("openingDate");
final String externalId = command.stringValueOfParameterNamed("externalId");
return new Office(parentOffice, name, openingDate, externalId);
}
protected Office() {
this.openingDate = null;
this.parent = null;
this.name = null;
this.externalId = null;
}
private Office(final Office parent, final String name, final LocalDate openingDate, final String externalId) {
this.parent = parent;
this.openingDate = openingDate.toDateTimeAtStartOfDay().toDate();
if (parent != null) {
this.parent.addChild(this);
}
if (StringUtils.isNotBlank(name)) {
this.name = name.trim();
} else {
this.name = null;
}
if (StringUtils.isNotBlank(externalId)) {
this.externalId = externalId.trim();
} else {
this.externalId = null;
}
}
private void addChild(final Office office) {
this.children.add(office);
}
public Map<String, Object> update(final JsonCommand command) {
final Map<String, Object> actualChanges = new LinkedHashMap<>(7);
final String dateFormatAsInput = command.dateFormat();
final String localeAsInput = command.locale();
final String parentIdParamName = "parentId";
if (command.parameterExists(parentIdParamName) && this.parent == null) { throw new RootOfficeParentCannotBeUpdated(); }
if (this.parent != null && command.isChangeInLongParameterNamed(parentIdParamName, this.parent.getId())) {
final Long newValue = command.longValueOfParameterNamed(parentIdParamName);
actualChanges.put(parentIdParamName, newValue);
}
final String openingDateParamName = "openingDate";
if (command.isChangeInLocalDateParameterNamed(openingDateParamName, getOpeningLocalDate())) {
final String valueAsInput = command.stringValueOfParameterNamed(openingDateParamName);
actualChanges.put(openingDateParamName, valueAsInput);
actualChanges.put("dateFormat", dateFormatAsInput);
actualChanges.put("locale", localeAsInput);
final LocalDate newValue = command.localDateValueOfParameterNamed(openingDateParamName);
this.openingDate = newValue.toDate();
}
final String nameParamName = "name";
if (command.isChangeInStringParameterNamed(nameParamName, this.name)) {
final String newValue = command.stringValueOfParameterNamed(nameParamName);
actualChanges.put(nameParamName, newValue);
this.name = newValue;
}
final String externalIdParamName = "externalId";
if (command.isChangeInStringParameterNamed(externalIdParamName, this.externalId)) {
final String newValue = command.stringValueOfParameterNamed(externalIdParamName);
actualChanges.put(externalIdParamName, newValue);
this.externalId = StringUtils.defaultIfEmpty(newValue, null);
}
return actualChanges;
}
public boolean isOpeningDateBefore(final LocalDate baseDate) {
return getOpeningLocalDate().isBefore(baseDate);
}
public boolean isOpeningDateAfter(final LocalDate activationLocalDate) {
return getOpeningLocalDate().isAfter(activationLocalDate);
}
public LocalDate getOpeningLocalDate() {
LocalDate openingLocalDate = null;
if (this.openingDate != null) {
openingLocalDate = LocalDate.fromDateFields(this.openingDate);
}
return openingLocalDate;
}
public void update(final Office newParent) {
if (this.parent == null) { throw new RootOfficeParentCannotBeUpdated(); }
if (identifiedBy(newParent.getId())) { throw new CannotUpdateOfficeWithParentOfficeSameAsSelf(getId(), newParent.getId()); }
this.parent = newParent;
generateHierarchy();
}
public boolean identifiedBy(final Long id) {
return getId().equals(id);
}
public void generateHierarchy() {
if (this.parent != null) {
this.hierarchy = this.parent.hierarchyOf(getId());
} else {
this.hierarchy = ".";
}
}
private String hierarchyOf(final Long id) {
return this.hierarchy + id.toString() + ".";
}
public String getName() {
return this.name;
}
public String getHierarchy() {
return this.hierarchy;
}
public Office getParent() {
return this.parent;
}
public boolean hasParentOf(final Office office) {
boolean isParent = false;
if (this.parent != null) {
isParent = this.parent.equals(office);
}
return isParent;
}
public boolean doesNotHaveAnOfficeInHierarchyWithId(final Long officeId) {
return !hasAnOfficeInHierarchyWithId(officeId);
}
private boolean hasAnOfficeInHierarchyWithId(final Long officeId) {
boolean match = false;
if (identifiedBy(officeId)) {
match = true;
}
if (!match) {
for (final Office child : this.children) {
final boolean result = child.hasAnOfficeInHierarchyWithId(officeId);
if (result) {
match = result;
break;
}
}
}
return match;
}
public void loadLazyCollections() {
this.children.size() ;
}
}
Any help will be much appreciated.
Using saveAndFlush where appropriate did the trick for me.
**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!');
})
}
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.
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?
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.