Spring MVC : Tying session attributes to each browser tab - java

I am working on Spring-MVC application in which I am setting and
getting some session attributes which I need in backend. The problem
is, Spring or the browser, someone out of the both is tying these
session attributes to different browsers rather than different tabs.
So if I open a new tab in the same browser, then it is updating the
session attribute for both tabs.
How can I remedy this problem? I tried using session to scope, request, etc. But nothing works. here is my controller and servlet-context.xml
Controller :
#Controller
#Scope("request")
public class PersonController {
#Secured("ROLE_USER")
#RequestMapping(value = "/loadsection/{id}")
public String loadNotePage(#PathVariable("id") Integer id, HttpSession session) {
// here i am setting the canvasid, which I would like to access in other methods
session.setAttribute("canvasid",id);
if (this.personService.returnCurrentOperationalMode()) {
session.setAttribute("canvasid",id);
return "redirect:/section/listing";
} else {
GroupCanvas mcanvas = this.groupCanvasService.getCanvasById(id);
this.personService.setCurrentCanvas(mcanvas.getMcanvasid());
return "redirect:/section/listing";
}
}
#Secured("ROLE_USER")
#RequestMapping(value = "/addbatchsections", method = RequestMethod.POST)
public #ResponseBody String addBatchSections(HttpSession session, #RequestBody Section[] sections) {
int canvasid = (Integer) session.getAttribute("canvasid");
try {
List<Section> sectionList = new ArrayList<>();
for (Section section : sections) {
sectionList.add(section);
}
this.sectionService.addBatchSections(sectionList,canvasid);
return "success";
} catch (Exception e) {
return "failure";
}
}
Servlet-Context.xml
<mvc:annotation-driven/>
<mvc:default-servlet-handler/>
<resources mapping="/resources/" location="/resources/" />
<beans:bean
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<beans:property name="prefix" value="/WEB-INF/views/" />
<beans:property name="suffix" value=".jsp" />
</beans:bean>
<beans:bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
destroy-method="close">
<beans:property name="driverClassName" value="org.postgresql.Driver" />
<beans:property name="url"
value="jdbc:postgresql://localhost:5432/Person2"/>
<beans:property name="username" value="postgres" />
<beans:property name="password" value="asayhk2787" />
<beans:property name="removeAbandoned" value="true"/>
<beans:property name="removeAbandonedTimeout" value="20"/>
<beans:property name="defaultAutoCommit" value="false"/>
</beans:bean>
<!-- Hibernate 4 SessionFactory Bean definition -->
<beans:bean id="hibernate4AnnotatedSessionFactory"
class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<beans:property name="dataSource" ref="dataSource" />
<beans:property name="annotatedClasses">
<beans:list>
<beans:value>com.journaldev.spring.model.Person</beans:value>
<beans:value>com.journaldev.spring.model.Notes</beans:value>
<beans:value>com.journaldev.spring.model.Canvas</beans:value>
<beans:value>com.journaldev.spring.model.Section</beans:value>
<beans:value>com.journaldev.spring.model.Attachment</beans:value>
<beans:value>com.journaldev.spring.model.GroupAccount</beans:value>
<beans:value>com.journaldev.spring.model.GroupMembers</beans:value>
<beans:value>com.journaldev.spring.model.GroupCanvas</beans:value>
<beans:value>com.journaldev.spring.model.GroupSection</beans:value>
<beans:value>com.journaldev.spring.model.GroupNotes</beans:value>
<beans:value>com.journaldev.spring.model.GroupAttachments</beans:value>
<beans:value>com.journaldev.spring.model.Token</beans:value>
<beans:value>com.journaldev.spring.model.WaitingMembers</beans:value>
<beans:value>com.journaldev.spring.model.NoteHistory</beans:value>
<beans:value>com.journaldev.spring.model.GroupNoteHistory</beans:value>
<beans:value>com.journaldev.spring.model.Feedback</beans:value>
</beans:list>
</beans:property>
<beans:property name="hibernateProperties">
<beans:props>
<beans:prop key="hibernate.dialect">org.hibernate.dialect.PostgreSQL82Dialect
</beans:prop>
<beans:prop key="hibernate.show_sql">false</beans:prop>
<beans:prop key="connection.pool_size">200</beans:prop>
<beans:prop key="c3p0.max_size">200</beans:prop>
<beans:prop key="c3p0.timeout">1000</beans:prop>
<beans:prop key="hibernate.jdbc.batch_size">100</beans:prop>
<beans:prop key="hibernate.order_updates">true</beans:prop>
</beans:props>
</beans:property>
</beans:bean>
<tx:annotation-driven transaction-manager="transactionManager" />
<beans:bean id="transactionManager"
class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<beans:property name="sessionFactory" ref="hibernate4AnnotatedSessionFactory"/>
</beans:bean>
I hope my question was clear, if there is any doubt, please feel free to ask me. Thanks a lot. :-)

Take a look at Spring Session and its associated examples.

Browsers like Chrome on new tab or new window share the user session because use the same session cookies.
Check this or change your session approach.

Related

Spring mvc mapping problems

I'm using spring mvc hibernate for a project.
Now i'm stuck on my mapping.
The normal url is:
localhost:8080/Carre2/......
Somepages have some parameters like
localhost:8080/Carre2/addproduct/edit/1
When i want to go to antoher page he request this:
localhost:8080/Carre2/addproduct/edit/home
I have no idea how to fix this mapping problem.
Someone can help?
Some code:
public class AddproductController {
private ProductService productService;
#Autowired(required = true)
#Qualifier(value = "productService")
public void setProductService(ProductService ps) {
this.productService = ps;
}
#RequestMapping(value = "/addproduct", method = RequestMethod.GET)
public String listProduct(Model model) {
model.addAttribute("product", new Product());
model.addAttribute("listProduct", this.productService.listProduct());
return "addproduct";
}
//For add and update person both
#RequestMapping(value = "/addproduct/add", method = RequestMethod.POST)
public String addProduct(#ModelAttribute("product") Product p) {
if (p.getId() == 0) {
//new person, add it
this.productService.addProduct(p);
} else {
//existing person, call update
this.productService.updateProduct(p);
}
return "redirect:/addproduct";
}
#RequestMapping("addproduct/update/{id}")
public String updateProduct(#PathVariable("id") int id, Model model) {
model.addAttribute("product", this.productService.getProductById(id));
model.addAttribute("listProduct", this.productService.listProduct());
return "productlist";
}
#RequestMapping("addproduct/edit/{id}")
public String editProduct(#PathVariable("id") int id, Model model) {
model.addAttribute("product", this.productService.getProductById(id));
model.addAttribute("listProduct", this.productService.listProduct());
return "addproduct";
}
Here my servlet-context.xml
<!-- DispatcherServlet Context: defines this servlet's request-processing
infrastructure -->
<!-- Resolves views selected for rendering by #Controllers to .jsp resources
in the /WEB-INF/views directory -->
<beans:bean
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<beans:property name="prefix" value="/WEB-INF/views/" />
<beans:property name="suffix" value=".jsp" />
</beans:bean>
<resources mapping="/resources/**" location="/resources/carre/" cache-period="31556926"/>
<!-- Enables the Spring MVC #Controller programming model -->
<annotation-driven />
<beans:bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
destroy-method="close">
<beans:property name="driverClassName" value="com.mysql.jdbc.Driver" />
<beans:property name="url"
value="jdbc:mysql://localhost:3306/carre" />
<beans:property name="username" value="root" />
<beans:property name="password" value="...." />
</beans:bean>
<!-- Hibernate 4 SessionFactory Bean definition -->
<beans:bean id="hibernate4AnnotatedSessionFactory"
class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<beans:property name="dataSource" ref="dataSource" />
<beans:property name="annotatedClasses">
<beans:list>
<beans:value>com.carre.model.Person</beans:value>
<beans:value>com.carre.model.Product</beans:value>
<beans:value>com.carre.model.Categorie</beans:value>
<beans:value>com.carre.model.Catalogus</beans:value>
<beans:value>com.carre.model.Voorstelling</beans:value>
</beans:list>
</beans:property>
<beans:property name="hibernateProperties">
<beans:props>
<beans:prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect
</beans:prop>
<beans:prop key="hibernate.show_sql">true</beans:prop>
</beans:props>
</beans:property>
</beans:bean>
<beans:bean id="catalogusDAO" class="com.carre.dao.CatalogusDAOImpl">
<beans:property name="sessionFactory" ref="hibernate4AnnotatedSessionFactory" />
</beans:bean>
<beans:bean id="CatalogusService" class="com.carre.service.CatalogusServiceImpl">
<beans:property name="catalogusDAO" ref="catalogusDAO"></beans:property>
</beans:bean>
<beans:bean id="personDAO" class="com.carre.dao.PersonDAOImpl">
<beans:property name="sessionFactory" ref="hibernate4AnnotatedSessionFactory" />
</beans:bean>
<beans:bean id="personService" class="com.carre.service.PersonServiceImpl">
<beans:property name="personDAO" ref="personDAO"></beans:property>
</beans:bean>
<beans:bean id="productDAO" class="com.carre.dao.ProductDAOImpl">
<beans:property name="sessionFactory" ref="hibernate4AnnotatedSessionFactory" />
</beans:bean>
<beans:bean id="productService" class="com.carre.service.ProductServiceImpl">
<beans:property name="productDAO" ref="productDAO"></beans:property>
</beans:bean>
<beans:bean id="categorieDAO" class="com.carre.dao.CategorieDAOImpl">
<beans:property name="sessionFactory" ref="hibernate4AnnotatedSessionFactory" />
</beans:bean>
<beans:bean id="CategorieService" class="com.carre.service.CategorieServiceImpl">
<beans:property name="categorieDAO" ref="categorieDAO"></beans:property>
</beans:bean>
<beans:bean id="voorstellingDAO" class="com.carre.dao.VoorstellingDAOImpl">
<beans:property name="sessionFactory" ref="hibernate4AnnotatedSessionFactory" />
</beans:bean>
<beans:bean id="VoorstellingService" class="com.carre.service.VoorstellingServiceImpl">
<beans:property name="voorstellingDAO" ref="voorstellingDAO"></beans:property>
</beans:bean>
<context:component-scan base-package="com.carre.controller" />
<tx:annotation-driven transaction-manager="transactionManager"/>
<beans:bean id="transactionManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<beans:property name="sessionFactory" ref="hibernate4AnnotatedSessionFactory" />
</beans:bean>
Here is how i want to get to the url.
c:url value='addproduct/edit/${product.id}'
I would recommend to use c:url like as below to fix it:
c:url value="${pageContext.request.contextPath}/addproduct/edit/${product.id}"
Basically try to take ${pageContext.request.contextPath} for each c:url
It will converted into "localhost:8080/Carre2"
You just need to access it as follows,
c:url value='/addproduct/edit/${product.id}'
This will make the url to start from your context path.
Or better way could be to store the context path globally and use it in each url. You can refer to context path as follows,
c:url value="${pageContext.request.contextPath}/addproduct/edit/${product.id}"

dificullty while using two databases in the spring hibernate application

I am trying to use 2 databases in my spring project. It is working fine if I use 1 database but when add other databases I am getting following error message.
org.hibernate.HibernateException: No Session found for current thread
dispatcher-servlet
<beans:bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<beans:property name="dataSource" ref="sample" />
<beans:property name="annotatedClasses">
<beans:list>
<beans:value>com.kendoui.spring.models.Constraint</beans:value>
</beans:list>
</beans:property>
<beans:property name="hibernateProperties">
<beans:props>
<beans:prop key="hibernate.dialect">org.hibernate.dialect.SQLServer2008Dialect
</beans:prop>
<beans:prop key="hibernate.show_sql">true</beans:prop>
<beans:prop key="hibernate.format_sql">true</beans:prop>
</beans:props>
</beans:property>
</beans:bean>
<beans:bean id="transactionManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<beans:property name="sessionFactory" ref="sessionFactory" />
</beans:bean>
<beans:bean id="Ascent" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<beans:property name="driverClassName" value="com.microsoft.sqlserver.jdbc.SQLServerDriver" />
<beans:property name="url" value="jdbc:sqlserver://localhost:1433;databaseName=Ascent;" />
<beans:property name="username" value="sa" />
<beans:property name="password" value="abc123" />
<beans:property name="maxActive" value="1" />
<beans:property name="maxIdle" value="1" />
</beans:bean>
<beans:bean id="sessionFactory2" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<beans:property name="dataSource" ref="Ascent" />
<beans:property name="annotatedClasses">
<beans:list>
<beans:value>com.kendoui.spring.models.ItemOperationSequence</beans:value>
</beans:list>
</beans:property>
<beans:property name="hibernateProperties">
<beans:props>
<beans:prop key="hibernate.dialect">org.hibernate.dialect.SQLServer2008Dialect</beans:prop>
<beans:prop key="hibernate.show_sql">true</beans:prop>
<beans:prop key="hibernate.format_sql">true</beans:prop>
</beans:props>
</beans:property>
</beans:bean>
<beans:bean id="transactionManager2" class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<beans:property name="sessionFactory" ref="sessionFactory2" />
</beans:bean>
<!-- Enable annotation driven transactions. Required by getCurrentSession(). -->
<tx:annotation-driven/>
DAO implemantation
#Transactional("transactionManager2")
#Component
public class ItemOprSeqDaoImpl implements ItemOprSeqDao {
#Autowired
private SessionFactory sessionFactory;
#Override
public List<ItemOperationSequence> getList(String Itemcode) {
Session session = sessionFactory.getCurrentSession();
String queryStr= "select * from [#is_itemtrvoprdetails]";
Query query= session.createSQLQuery(queryStr).addEntity(ItemOperationSequence.class);
List <ItemOperationSequence> d=query.list();
return d;
}
}
I tried many different things but it is not working.
I tried using <beans:qualifier value="Ascent" /> in my servlet
and
#Qualifier(value="SessionFactory2") in my DAO
but nothing seems to work.
Anyone knows the answer to this problem. I would really appreciate if you could help.
Thanks in advance.
<tx:annotation-driven/> should be declared twice once for each transaction manager.
<tx:annotation-driven transaction-manager="transactionManager2"/>
and
<tx:annotation-driven transaction-manager="transactionManager"/>
Also add #Qualifier for
#Autowired
#Qualifier(value="SessionFactory2")
private SessionFactory sessionFactory;
You need to define a ChainedTransactionManager with both HibernateTransactionManagers as input.
I am not used to spring xml configuration, but it should look like this.
Than just use only #Transactional without a value.
<beans:bean id="transactionManager1" class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<beans:property name="sessionFactory" ref="sessionFactory" />
</beans:bean>
<beans:bean id="transactionManager2" class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<beans:property name="sessionFactory" ref="sessionFactory2" />
</beans:bean>
<beans:bean id="transactionManager" class="org.springframework.data.transaction.ChainedTransactionManager">
<beans:constructor-arg>
<list>
<beans:ref bean="transactionManager1" />
<beans:ref bean="transactionManager2" />
</list>
</beans:constructor-arg>
</beans:bean>
Okay I solved the problem by doing this.
first declared transaction-manager
<tx:annotation-driven transaction-manager="transactionManager1"/>
Then in my DAO used
#Transactional("transactionManager2")
#Component
public class ItemOprSeqDaoImpl implements ItemOprSeqDao {
#Autowired
#Qualifier("sessionFactory2")
private SessionFactory sessionFactory;
//then rest of the code
}
Its working fine now. Thanks you guys for your help.

How to insert into database when using JTA + JPA with Spring

I have a simple web application using JTA + JPA along with Spring (version 4).
I am doing a XA transaction using Atomikos JTA transaction Manager. This transaction involves inserting EmployeeA entity into DatabaseA and another EmployeeB entity into another DatabaseB.
Strangely, the application does not throw any error but no enteries are inserted into the Databases.
public class JtaTest {
public static void main( String[] args ) {
JtaTest test = new JtaTest();
test.testMandatory();
}
private static void testMandatory() {
final SpringContextUtil util = SpringContextUtil.instance();
ApplicationContext ctx = util.getApplicationContext();
final JtaEmployeeService employeeService = (JtaEmployeeService)ctx.getBean("jtaEmployeeService");
EmployeeA a = new EmployeeA();
a.setName("emp-a-1");
a.setAge(30);
EmployeeB b = new EmployeeB();
a.setName("emp-b-1");
a.setAge(31);
try {
employeeService.persistEmployees(a, b);
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("success");
}
}
The service class implementation:
#Service("jtaEmployeeService")
public class JtaEmployeeServiceImpl implements JtaEmployeeService {
#Autowired
#Qualifier("employeea")
private GenericDao<Integer, EmployeeA> employeeADao;
#Autowired
#Qualifier("employeeb")
private GenericDao<Integer, EmployeeB> employeeBDao;
#Override
#Transactional( propagation=Propagation.REQUIRED, readOnly=false, isolation=Isolation.DEFAULT, rollbackFor=Exception.class)
public void persistEmployees(EmployeeA employeeA, EmployeeB employeeB) throws Exception {
employeeADao.save(employeeA);
employeeBDao.save(employeeB);
System.out.println("Saving employee A and employee B ");
}
}
The DAO implementation and interfaces:
#Repository("employeeb")
public class EmployeeBDaoImpl extends AbstractJTADaoDatabaseB implements
GenericDao<Integer, EmployeeB> {
#Override
public void save(EmployeeB entity) {
super.persist(entity);
}
}
#Repository("employeea")
public class EmployeeADaoImpl extends AbstractJTADaoDatabaseA implements
GenericDao<Integer, EmployeeA> {
#Override
public void save(EmployeeA entity) {
super.persist(entity);
}
}
public abstract class AbstractJTADaoDatabaseB {
#PersistenceContext(unitName = "persistenceUnitB")
#Qualifier("myManager")
private EntityManager entityManager;
public void persist(Object entity) {
entityManager.persist(entity);
// entityManager.flush();
}
protected EntityManager getEntityManager() {
return entityManager;
}
}
public abstract class AbstractJTADaoDatabaseA {
#PersistenceContext(unitName = "persistenceUnitA")
#Qualifier("myManager")
private EntityManager entityManager;
public void persist(Object entity) {
entityManager.persist(entity);
// entityManager.flush();
}
protected EntityManager getEntityManager() {
return entityManager;
}
}
Servlet-Context.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="http://www.springframework.org/schema/mvc"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:beans="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd
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/tx http://www.springframework.org/schema/tx/spring-tx.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">
<!-- DispatcherServlet Context: defines this servlet's request-processing infrastructure -->
<!-- Enables the Spring MVC #Controller programming model -->
<annotation-driven />
<!-- Enables annotaion driven transactional support on springs -->
<!-- <tx:annotation-driven transaction-manager="hTransactionManager"/> -->
<!-- <tx:jta-transaction-manager transaction-manager="jtaTransactionManager"/> -->
<tx:annotation-driven transaction-manager="jtaTransactionManager"/>
<!-- list the packages which are annotated with springs annotaions like #controller, #repository, #service, #component only -->
<context:component-scan base-package="com.goraksh.spring.tutorial.controller.business, com.goraksh.spring.tutorial.controller.rest, com.goraksh.spring.tutorial.service, com.goraksh.spring.tutorial.dao" />
<beans:bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<beans:property name="prefix" value="/WEB-INF/views/" />
<beans:property name="suffix" value=".jsp" />
</beans:bean>
<beans:bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<beans:property name="location" value="classpath:application.properties"/>
</beans:bean>
<!-- <beans:bean id="sessionFactory" class="org.springframework.orm.hibernate4.annotation.AnnotationSessionFactoryBean"> -->
<beans:bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<beans:property name="dataSource" ref="dataSource" />
<beans:property name="hibernateProperties">
<beans:props>
<beans:prop key="hibernate.dialect">org.hibernate.dialect.SQLServerDialect</beans:prop>
<!-- <beans:prop key="hibernate.current_session_context_class">thread</beans:prop> -->
<beans:prop key="hibernate.show_sql">${hibernate.show_sql}</beans:prop>
<beans:prop key="hibernate.format_sql">${hibernate.format_sql}</beans:prop>
<beans:prop key="hibernate.cache.region.factory_class">${hibernate.cache.region.factory_class}</beans:prop>
<beans:prop key="hibernate.cache.use_second_level_cache">${hibernate.cache.use_second_level_cache}</beans:prop>
<beans:prop key="hibernate.cache.use_query_cache">${hibernate.cache.use_query_cache}</beans:prop>
<beans:prop key="net.sf.ehcache.configurationResourceName">${net.sf.ehcache.configurationResourceName}</beans:prop>
</beans:props>
</beans:property>
<!--<beans:property name="annotatedClasses"> -->
<!-- packagesToScan is meant to give the package where the javax.persistence.Entity classes are stored , recognised via their annotations-->
<beans:property name="packagesToScan">
<beans:list>
<beans:value>com.goraksh.spring.tutorial.model</beans:value>
</beans:list>
</beans:property>
</beans:bean>
<beans:bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<beans:property name="driverClassName" value="${jdbc.driverClassName}"/>
<beans:property name="url" value="${jdbc.url}"/>
<beans:property name="username" value="${jdbc.username}"/>
<beans:property name="password" value="${jdbc.password}"/>
</beans:bean>
<beans:bean id = "hTransactionManager" class = "org.springframework.orm.hibernate4.HibernateTransactionManager">
<beans:property name = "sessionFactory" ref = "sessionFactory" />
</beans:bean>
<!-- Jata transactions with Atomikos -->
<beans:bean id="dataSourceA" class="com.atomikos.jdbc.AtomikosDataSourceBean" init-method="init" destroy-method="close">
<beans:property name="uniqueResourceName"><beans:value>DataSourceA</beans:value></beans:property>
<beans:property name="xaDataSourceClassName"><beans:value>com.mysql.jdbc.jdbc2.optional.MysqlXADataSource</beans:value></beans:property>
<beans:property name="xaProperties">
<beans:props>
<beans:prop key="databaseName">traningdb</beans:prop>
<beans:prop key="serverName">localhost</beans:prop>
<beans:prop key="port">3306</beans:prop>
<beans:prop key="user">root</beans:prop>
<beans:prop key="password">root</beans:prop>
<beans:prop key="url">jdbc:mysql://localhost:3306/traningdb</beans:prop>
</beans:props>
</beans:property>
<beans:property name="minPoolSize"><beans:value>1</beans:value></beans:property>
</beans:bean>
<beans:bean id="dataSourceB" class="com.atomikos.jdbc.AtomikosDataSourceBean" init-method="init" destroy-method="close">
<beans:property name="uniqueResourceName"><beans:value>DataSourceB</beans:value></beans:property>
<beans:property name="xaDataSourceClassName"><beans:value>com.mysql.jdbc.jdbc2.optional.MysqlXADataSource</beans:value></beans:property>
<beans:property name="xaProperties">
<beans:props>
<beans:prop key="databaseName">traningdb2</beans:prop>
<beans:prop key="serverName">localhost</beans:prop>
<beans:prop key="port">3306</beans:prop>
<beans:prop key="user">root</beans:prop>
<beans:prop key="password">root</beans:prop>
<beans:prop key="url">jdbc:mysql://localhost:3306/traningdb2</beans:prop>
</beans:props>
</beans:property>
<beans:property name="minPoolSize">
<beans:value>1</beans:value>
</beans:property>
</beans:bean>
<beans:bean id="entityManagerFactoryA" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<beans:property name="persistenceXmlLocation">
<beans:value>classpath:META-INF/persistence.xml</beans:value>
</beans:property>
<beans:property name="persistenceUnitName" value="persistenceUnitA" />
<beans:property name="dataSource" ref="dataSourceA" />
<beans:property name="jpaVendorAdapter">
<beans:bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
<beans:property name="showSql" value="true" />
<beans:property name="databasePlatform" value="org.hibernate.dialect.MySQL5InnoDBDialect" />
</beans:bean>
</beans:property>
</beans:bean>
<beans:bean id="entityManagerFactoryB" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<beans:property name="persistenceXmlLocation">
<beans:value>classpath:META-INF/persistence.xml</beans:value>
</beans:property>
<beans:property name="persistenceUnitName" value="persistenceUnitB" />
<beans:property name="dataSource" ref="dataSourceB" />
<beans:property name="jpaVendorAdapter">
<beans:bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
<beans:property name="showSql" value="true" />
<beans:property name="databasePlatform" value="org.hibernate.dialect.MySQL5InnoDBDialect" />
</beans:bean>
</beans:property>
</beans:bean>
<beans:bean id="atomikosTransactionManager" class="com.atomikos.icatch.jta.UserTransactionManager" init-method="init" destroy-method="close">
<beans:property name="forceShutdown" value="false" />
<!-- <beans:property name="startupTransactionService" value="false" /> -->
</beans:bean>
<beans:bean id="atomikosUserTransaction" class="com.atomikos.icatch.jta.UserTransactionImp">
<beans:property name="transactionTimeout" value="300" />
</beans:bean>
<beans:bean id="jtaTransactionManager" class="org.springframework.transaction.jta.JtaTransactionManager"
depends-on="atomikosTransactionManager,atomikosUserTransaction">
<beans:qualifier value="myManager"/>
<beans:property name="transactionManager" ref="atomikosTransactionManager" />
<beans:property name="userTransaction" ref="atomikosUserTransaction" />
<beans:property name="allowCustomIsolationLevels" value="true" />
</beans:bean>
</beans:beans>
Persistence.xml
<?xml version="1.0" encoding="UTF-8"?>
<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="persistenceUnitA" >
<class>com.goraksh.spring.tutorial.model.EmployeeA</class>
<exclude-unlisted-classes />
<properties>
<property name="hibernate.cache.region.factory_class" value="org.hibernate.cache.ehcache.SingletonEhCacheRegionFactory" />
</properties>
</persistence-unit>
<persistence-unit name="persistenceUnitB" >
<class>com.goraksh.spring.tutorial.model.EmployeeB</class>
<exclude-unlisted-classes />
<properties>
<property name="hibernate.cache.region.factory_class" value="org.hibernate.cache.ehcache.SingletonEhCacheRegionFactory" />
</properties>
</persistence-unit>
</persistence>
Any help is highly solicited.
After lot of head-whacking and many hit-and-trial debugging, finally able to solve the problem.
Looks like below property is required in the persistence.xml
hibernate.transaction.jta.platform
On a application server there are multiple options available as Different JTA paltform services
But since I needed one standalone JTA platform implementation so I added one of my own.
com.goraksh.spring.atomikos.jta.platform.AtomikosJtaPlatform
So here is my modified persistence.xml:
<?xml version="1.0" encoding="UTF-8"?>
<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="persistenceUnitA" transaction-type="JTA" >
<class>com.goraksh.spring.tutorial.model.EmployeeA</class>
<exclude-unlisted-classes />
<properties>
<property name="hibernate.transaction.jta.platform" value="com.goraksh.spring.atomikos.jta.platform.AtomikosJtaPlatform" />
<property name="hibernate.cache.region.factory_class" value="org.hibernate.cache.ehcache.SingletonEhCacheRegionFactory" />
</properties>
</persistence-unit>
<persistence-unit name="persistenceUnitB" transaction-type="JTA">
<class>com.goraksh.spring.tutorial.model.EmployeeB</class>
<exclude-unlisted-classes />
<properties>
<property name="hibernate.transaction.jta.platform" value="com.goraksh.spring.atomikos.jta.platform.AtomikosJtaPlatform" />
<property name="hibernate.cache.region.factory_class" value="org.hibernate.cache.ehcache.SingletonEhCacheRegionFactory" />
</properties>
</persistence-unit>
</persistence>
The source code for com.goraksh.spring.atomikos.jta.platform.AtomikosJtaPlatform
package com.goraksh.spring.atomikos.jta.platform;
import javax.transaction.TransactionManager;
import javax.transaction.UserTransaction;
import org.hibernate.engine.transaction.jta.platform.internal.AbstractJtaPlatform;
import com.atomikos.icatch.jta.UserTransactionImp;
import com.atomikos.icatch.jta.UserTransactionManager;
public final class AtomikosJtaPlatform extends AbstractJtaPlatform {
private TransactionManager utm = new UserTransactionManager();
private UserTransaction userTransaction = new UserTransactionImp();
/**
*
*/
private static final long serialVersionUID = -74991083213512919L;
#Override
protected TransactionManager locateTransactionManager() {
return utm;
}
#Override
protected UserTransaction locateUserTransaction() {
return userTransaction;
}
}
After some additional tuning:
1. Removing all hibernate ( jpa properties ) from persistence.xml to the servlet-context.xml.
Added jpaProperties to EntityManagerFactoryA and EntityManagerFactoryB
Servlet-context.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="http://www.springframework.org/schema/mvc"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:beans="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd
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/tx http://www.springframework.org/schema/tx/spring-tx.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">
<!-- DispatcherServlet Context: defines this servlet's request-processing infrastructure -->
<!-- Enables the Spring MVC #Controller programming model -->
<annotation-driven />
<!-- Enables annotaion driven transactional support on springs -->
<!-- <tx:annotation-driven transaction-manager="hTransactionManager"/> -->
<!-- <tx:jta-transaction-manager transaction-manager="jtaTransactionManager"/> -->
<tx:annotation-driven transaction-manager="jtaTransactionManager"/>
<!-- list the packages which are annotated with springs annotaions like #controller, #repository, #service, #component only -->
<context:component-scan base-package="com.goraksh.spring.tutorial.controller.business, com.goraksh.spring.tutorial.controller.rest, com.goraksh.spring.tutorial.service, com.goraksh.spring.tutorial.dao" />
<beans:bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<beans:property name="prefix" value="/WEB-INF/views/" />
<beans:property name="suffix" value=".jsp" />
</beans:bean>
<beans:bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<beans:property name="location" value="classpath:application.properties"/>
</beans:bean>
<!-- <beans:bean id="sessionFactory" class="org.springframework.orm.hibernate4.annotation.AnnotationSessionFactoryBean"> -->
<beans:bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<beans:property name="dataSource" ref="dataSource" />
<beans:property name="hibernateProperties">
<beans:props>
<beans:prop key="hibernate.dialect">org.hibernate.dialect.SQLServerDialect</beans:prop>
<!-- <beans:prop key="hibernate.current_session_context_class">thread</beans:prop> -->
<beans:prop key="hibernate.show_sql">${hibernate.show_sql}</beans:prop>
<beans:prop key="hibernate.format_sql">${hibernate.format_sql}</beans:prop>
<beans:prop key="hibernate.cache.region.factory_class">${hibernate.cache.region.factory_class}</beans:prop>
<beans:prop key="hibernate.cache.use_second_level_cache">${hibernate.cache.use_second_level_cache}</beans:prop>
<beans:prop key="hibernate.cache.use_query_cache">${hibernate.cache.use_query_cache}</beans:prop>
<beans:prop key="net.sf.ehcache.configurationResourceName">${net.sf.ehcache.configurationResourceName}</beans:prop>
</beans:props>
</beans:property>
<!--<beans:property name="annotatedClasses"> -->
<!-- packagesToScan is meant to give the package where the javax.persistence.Entity classes are stored , recognised via their annotations-->
<beans:property name="packagesToScan">
<beans:list>
<beans:value>com.goraksh.spring.tutorial.model</beans:value>
</beans:list>
</beans:property>
</beans:bean>
<beans:bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<beans:property name="driverClassName" value="${jdbc.driverClassName}"/>
<beans:property name="url" value="${jdbc.url}"/>
<beans:property name="username" value="${jdbc.username}"/>
<beans:property name="password" value="${jdbc.password}"/>
</beans:bean>
<beans:bean id = "hTransactionManager" class = "org.springframework.orm.hibernate4.HibernateTransactionManager">
<beans:property name = "sessionFactory" ref = "sessionFactory" />
</beans:bean>
<!-- Jata transactions with Atomikos -->
<beans:bean id="dataSourceA" class="com.atomikos.jdbc.AtomikosDataSourceBean" init-method="init" destroy-method="close">
<beans:property name="uniqueResourceName"><beans:value>DataSourceA</beans:value></beans:property>
<beans:property name="xaDataSourceClassName"><beans:value>com.mysql.jdbc.jdbc2.optional.MysqlXADataSource</beans:value></beans:property>
<beans:property name="xaProperties">
<beans:props>
<beans:prop key="databaseName">traningdb</beans:prop>
<beans:prop key="serverName">localhost</beans:prop>
<beans:prop key="port">3306</beans:prop>
<beans:prop key="user">root</beans:prop>
<beans:prop key="password">root</beans:prop>
<beans:prop key="url">jdbc:mysql://localhost:3306/traningdb</beans:prop>
</beans:props>
</beans:property>
<beans:property name="minPoolSize"><beans:value>1</beans:value></beans:property>
</beans:bean>
<beans:bean id="dataSourceB" class="com.atomikos.jdbc.AtomikosDataSourceBean" init-method="init" destroy-method="close">
<beans:property name="uniqueResourceName"><beans:value>DataSourceB</beans:value></beans:property>
<beans:property name="xaDataSourceClassName"><beans:value>com.mysql.jdbc.jdbc2.optional.MysqlXADataSource</beans:value></beans:property>
<beans:property name="xaProperties">
<beans:props>
<beans:prop key="databaseName">traningdb2</beans:prop>
<beans:prop key="serverName">localhost</beans:prop>
<beans:prop key="port">3306</beans:prop>
<beans:prop key="user">root</beans:prop>
<beans:prop key="password">root</beans:prop>
<beans:prop key="url">jdbc:mysql://localhost:3306/traningdb2</beans:prop>
</beans:props>
</beans:property>
<beans:property name="minPoolSize">
<beans:value>1</beans:value>
</beans:property>
</beans:bean>
<beans:bean id="entityManagerFactoryA" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<beans:property name="persistenceXmlLocation">
<beans:value>classpath:META-INF/persistence.xml</beans:value>
</beans:property>
<beans:property name="persistenceUnitName" value="persistenceUnitA" />
<beans:property name="dataSource" ref="dataSourceA" />
<beans:property name="jpaVendorAdapter">
<beans:bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
<beans:property name="showSql" value="true" />
<beans:property name="databasePlatform" value="org.hibernate.dialect.MySQL5InnoDBDialect" />
</beans:bean>
</beans:property>
<beans:property name="jpaProperties">
<beans:map>
<beans:entry key="hibernate.transaction.jta.platform" value-ref="atomikosJtaPlatform" />
<beans:entry key="hibernate.cache.region.factory_class" value="org.hibernate.cache.ehcache.SingletonEhCacheRegionFactory" />
</beans:map>
</beans:property>
</beans:bean>
<beans:bean id="entityManagerFactoryB" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<beans:property name="persistenceXmlLocation">
<beans:value>classpath:META-INF/persistence.xml</beans:value>
</beans:property>
<beans:property name="persistenceUnitName" value="persistenceUnitB" />
<beans:property name="dataSource" ref="dataSourceB" />
<beans:property name="jpaVendorAdapter">
<beans:bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
<beans:property name="showSql" value="true" />
<beans:property name="databasePlatform" value="org.hibernate.dialect.MySQL5InnoDBDialect" />
</beans:bean>
</beans:property>
<beans:property name="jpaProperties">
<beans:map>
<beans:entry key="hibernate.transaction.jta.platform" value-ref="atomikosJtaPlatform" />
<beans:entry key="hibernate.cache.region.factory_class" value="org.hibernate.cache.ehcache.SingletonEhCacheRegionFactory" />
</beans:map>
</beans:property>
</beans:bean>
<beans:bean id="atomikosJtaPlatform" class="com.goraksh.spring.atomikos.jta.platform.AtomikosJtaPlatform">
<beans:constructor-arg index="0" ref="atomikosTransactionManager"/>
<beans:constructor-arg index="1" ref="atomikosUserTransaction"/>
</beans:bean>
<beans:bean id="atomikosTransactionManager" class="com.atomikos.icatch.jta.UserTransactionManager" init-method="init" destroy-method="close">
<beans:property name="forceShutdown" value="false" />
<!-- <beans:property name="startupTransactionService" value="false" /> -->
</beans:bean>
<beans:bean id="atomikosUserTransaction" class="com.atomikos.icatch.jta.UserTransactionImp">
<beans:property name="transactionTimeout" value="300" />
</beans:bean>
<beans:bean id="jtaTransactionManager" class="org.springframework.transaction.jta.JtaTransactionManager"
depends-on="atomikosTransactionManager,atomikosUserTransaction">
<beans:qualifier value="myManager"/>
<beans:property name="transactionManager" ref="atomikosTransactionManager" />
<beans:property name="userTransaction" ref="atomikosUserTransaction" />
<beans:property name="allowCustomIsolationLevels" value="true" />
</beans:bean>
</beans:beans>
Persistence.xml
<?xml version="1.0" encoding="UTF-8"?>
<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="persistenceUnitA" transaction-type="JTA" >
<class>com.goraksh.spring.tutorial.model.EmployeeA</class>
<exclude-unlisted-classes />
<properties>
<!-- <property name="hibernate.transaction.jta.platform" value="com.goraksh.spring.atomikos.jta.platform.AtomikosJtaPlatform" /> -->
</properties>
</persistence-unit>
<persistence-unit name="persistenceUnitB" transaction-type="JTA">
<class>com.goraksh.spring.tutorial.model.EmployeeB</class>
<exclude-unlisted-classes />
<properties>
<!-- <property name="hibernate.transaction.jta.platform" value="com.goraksh.spring.atomikos.jta.platform.AtomikosJtaPlatform" /> -->
</properties>
</persistence-unit>
</persistence>

Spring batch is getting stopped while updating more than 1000 records through itemwriter class

I'm using Spring batch to read and update same DB table through JPAPagingItemReader and customized Itemwriter class using Open JPA.
But, while trying to update more than 1000 records, some of the records are not updated and batch is getting stopped with either of batch statuses STOPPED, FAILED, UNKNOWN (with no Exceptions during batch process)
The below is what I'm doing in my code
1) Reader -
<beans:bean id="dataReader"
class="org.springframework.batch.item.database.JpaPagingItemReader" scope="step">
<beans:property name="entityManagerFactory" ref="entityManagerFactory" />
<beans:property name="pageSize" value="1"/>
<beans:property name="queryString"
value="select b from Test b where b.testStatus = #{jobParameters[status]}"/> <!—here status value is ‘No’ -->
</beans:bean>
2) Processor –
Doing some business logic depends on some condition
3) Writer –
<beans:bean id="dataWriter"
class="com.example.batch..DataWriter">
<beans:property name="entityManager" ref="sharedEntityManager" />
</beans:bean>
public class DataWriter implements ItemWriter<TestData> {
private EntityManager entityManager;
public EntityManager getEntityManager() {
return this.entityManager;
}
public void setEntityManager(EntityManager entityManager) {
this.entityManager = entityManager;
}
#Transactional
public void write (List<? extends TestData> items) {
try {
for (TestData testData : items) {
updateTestDataStatus(testData.getTestDataKey());
}
} catch (Exception e) {
e.printStackTrace();
}
}
private void updateTestDataStatus(String testDataKey) {
Test test = getEntityManager().find(Test.class, testDataKey); //getEntityManager is sharedEntityManager
test.setTestStatus("Yes");
getEntityManager().persist(test);
}
}
4) DB config
<tx:annotation-driven transaction-manager="transactionManager" />
<beans:bean id="sharedEntityManager"
class="org.springframework.orm.jpa.support.SharedEntityManagerBean">
<beans:property name="entityManagerFactory" ref="entityManagerFactory" />
</beans:bean>
<!-- Configuration for JPATransaction Manager -->
<beans:bean id="transactionManager"
class="org.springframework.orm.jpa.JpaTransactionManager">
<beans:property name="entityManagerFactory" ref="entityManagerFactory" />
</beans:bean>
<!-- Configuration for EntityManager -->
<beans:bean id="entityManagerFactory"
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<beans:property name="dataSource" ref="dataSource" />
<beans:property name="persistenceUnitName" value="testdata-pu" />
<beans:property name="jpaVendorAdapter">
<beans:bean class="org.springframework.orm.jpa.vendor.OpenJpaVendorAdapter">
<beans:property name="databasePlatform"
value="org.apache.openjpa.jdbc.sql.OracleDictionary" />
<beans:property name="database" value="ORACLE" />
<beans:property name="showSql" value="true" />
</beans:bean>
</beans:property>
</beans:bean>
<!-- Configuration for Data Source -->
<beans:bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
destroy-method="close">
<beans:property name="driverClassName" value="${database.driverClassName}" />
<beans:property name="url" value="${database.url}" />
<beans:property name="username" value="${database.username}" />
<beans:property name="password" value="${database.password}" />
</beans:bean>
<beans:bean id="dataSourcePropertiesplaceholder" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer" >
<beans:property name="location" value="classpath:datasource.properties"/>
</beans:bean>
<!-- jobRepository - in-memory mapping configuration -->
<beans:bean id="jobRepository"
class="org.springframework.batch.core.repository.support.MapJobRepositoryFactoryBean">
<beans:property name="transactionManager" ref="jobRepository-transactionManager" />
</beans:bean>
<beans:bean id="jobRepository-transactionManager"
class="org.springframework.batch.support.transaction.ResourcelessTransactionManager" />

Spring URL matching case-insensitive does not map when there are numbers in the url

I was trying to make my URL case-insensitive and got the following code from the net.
However now when my urls are having number it is giving me Status 400 error. It was working fine before this change. Url like localhost\toplevel\234\text\2342 are not recognized now. Can someone please help explaining why this is happening and what need to be changed to make those urls work.
public class CaseInsensitiveAnnotationHandlerMapping extends AntPathMatcher
protected boolean doMatch(String pattern,
String path, boolean fullMatch, Map<String, String> uriTemplateVariables) {
return super.doMatch(pattern.toLowerCase(),
path.toLowerCase(), fullMatch, uriTemplateVariables);
}
}
my Servlet-Context.xml
<beans:bean class="com.darproject.webUtils.CaseInsensitiveAnnotationHandlerMapping" />
<beans:bean id="validator" class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean" />
<beans:bean id="conversion-service" class="org.springframework.format.support.FormattingConversionServiceFactoryBean" />
<beans:bean name="handlerAdapter" class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter">
<beans:property name="webBindingInitializer">
<beans:bean class="org.springframework.web.bind.support.ConfigurableWebBindingInitializer">
<beans:property name="conversionService" ref="conversion-service"></beans:property>
<beans:property name="validator">
<beans:bean class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean">
<beans:property name="providerClass" value="org.hibernate.validator.HibernateValidator"></beans:property>
</beans:bean>
</beans:property>
</beans:bean>
</beans:property>
<beans:property name="messageConverters">
<beans:list>
<beans:ref bean="byteArrayConverter"/>
<beans:ref bean="jaxbConverter"/>
<beans:ref bean="jsonConverter"/>
<beans:bean class="org.springframework.http.converter.StringHttpMessageConverter"></beans:bean>
<beans:bean class="org.springframework.http.converter.ResourceHttpMessageConverter"></beans:bean>
<beans:bean class="org.springframework.http.converter.xml.SourceHttpMessageConverter"></beans:bean>
<beans:bean class="org.springframework.http.converter.xml.XmlAwareFormHttpMessageConverter"></beans:bean>
</beans:list>
</beans:property>
</beans:bean>
<beans:bean name="byteArrayConverter" class="org.springframework.http.converter.ByteArrayHttpMessageConverter"></beans:bean>
<beans:bean name="jaxbConverter" class="org.springframework.http.converter.xml.Jaxb2RootElementHttpMessageConverter"></beans:bean>
<beans:bean name="jsonConverter" class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter"></beans:bean>
<beans:bean name="caseInsensitivePathMatcher" class="com.darproject.webUtils.CaseInsensitiveAnnotationHandlerMapping"/>
<beans:bean name="handlerMapping" class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping">
<beans:property name="pathMatcher" ref="caseInsensitivePathMatcher"></beans:property>
</beans:bean>
Methods that are not working now.
#RequestMapping(value="/commentswindow/{defectId}/{release}/{defectsRowID}",method=RequestMethod.POST)
public String addUserComments(
#PathVariable("defectsRowID") long defectsRowID,
#PathVariable("defectId") String defectId,
#PathVariable("release") String release,
#ModelAttribute("addComments") UserCommentsModel cmtModel,
BindingResult results,
Model model,
HttpServletRequest request,
HttpServletResponse response){
The case-insensitive conflicts with path variable mapping. You can change your variable name to all lowercase: defectId --> defectid. It should work.
#RequestMapping(value="/commentswindow/{defectid}/{release}/{defectsrowid}",method=RequestMethod.POST)public String addUserComments(
#PathVariable("defectsrowid") long defectsRowID,
#PathVariable("defectid") String defectId,
#PathVariable("release") String release,
#ModelAttribute("addComments") UserCommentsModel cmtModel,
BindingResult results,
Model model,
HttpServletRequest request,
HttpServletResponse response){

Categories