I'm trying to set up and Spring MVC + Hibernate project but it's driving me nuts. I would also take in account suggestions to order the xml config files.
I have the following files:
web.xml
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"> <!-- The definition of the Root Spring Container shared by all Servlets and Filters --> <context-param> <param-name>contextConfigLocation</param-name> <param-value>/WEB-INF/spring/root-context.xml</param-value> </context-param> <!-- Creates the Spring Container shared by all Servlets and Filters --> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> <!-- Processes application requests --> <servlet> <servlet-name>appServlet</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <init-param> <param-name>contextConfigLocation</param-name> <param-value>/WEB-INF/spring/appServlet/servlet-context.xml</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>appServlet</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping> </web-app>
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:tx="http://www.springframework.org/schema/tx" xmlns:jdbc="http://www.springframework.org/schema/jdbc" 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/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-3.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> <context:annotation-config /> <!-- DispatcherServlet Context: defines this servlet's request-processing infrastructure --> <!-- Enables the Spring MVC @Controller programming model --> <annotation-driven /> <tx:annotation-driven/> <context:component-scan base-package="es.landesoft.mvctesting" /> <context:component-scan base-package="es.landesoft.mvctesting.service" /> <context:component-scan base-package="es.landesoft.mvctesting.dao" /> <!-- Handles HTTP GET requests for /resources/** by efficiently serving up static resources in the ${webappRoot}/resources directory --> <resources mapping="/resources/**" location="/resources/" /> <!-- 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> <!-- JDBC Data Source. It is assumed you have MySQL running on localhost port 3306 with username root and blank password. Change below if it's not the case --> <beans:bean id="myDataSource" 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://127.0.0.1:1433;databaseName=MyHome;instanceName=SQLEXPRESS;"/> <beans:property name="username" value="sa"/> <beans:property name="password" value="sarednal1"/> <beans:property name="validationQuery" value="SELECT 1"/> </beans:bean> <beans:bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean"> <beans:property name="dataSource" ref="myDataSource"/> <beans:property name="configLocation"> <beans:value>classpath:hibernate.cfg.xml</beans:value> </beans:property> <beans:property name="packagesToScan" value="es.landesoft.mvctesting" /> <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:props> </beans:property> </beans:bean> <beans:bean id="transactionManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager"> <beans:property name="dataSource" ref="myDataSource" /> <beans:property name="sessionFactory" ref="sessionFactory" /> </beans:bean>
PersonController.java
package es.landesoft.mvctesting; import java.util.List; import java.util.Locale; import javax.validation.Valid; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.validation.BindingResult; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.ResponseBody; import es.landesoft.mvctesting.JavaBeans.Person; import es.landesoft.mvctesting.service.PersonService; /** * Handles requests for the application home page. */ @Controller public class PersonController { //private static final Logger logger = LoggerFactory.getLogger(PersonController.class); @Autowired private PersonService personService; @RequestMapping(value = "/person/json", method = RequestMethod.GET, produces="application/json") @ResponseBody public List<Person> getPersonJson() { return personService.listPerson(); } }
PersonDAO.java
package es.landesoft.mvctesting.dao;
import java.util.List; import es.landesoft.mvctesting.JavaBeans.Person; public interface PersonDAO { public void addContact(Person person); public List<Person> listPersons(); public void removePerson(Integer id); }
PersonDaoClass.java
package es.landesoft.mvctesting.dao; import java.util.List; import org.hibernate.SessionFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Repository; import org.springframework.transaction.annotation.Transactional; import es.landesoft.mvctesting.JavaBeans.Person; @Repository public class PersonDaoClass implements PersonDAO { @Autowired private SessionFactory sessionFactory; @Transactional @Override public void addContact(Person person) { sessionFactory.getCurrentSession().save(person); } @Transactional @SuppressWarnings("unchecked") public List<Person> listPersons() { return sessionFactory.getCurrentSession() .createQuery("From Person").list(); } @Transactional public void removePerson(Integer id) { Person person = (Person) sessionFactory.getCurrentSession().load(Person.class, id); if (person != null) { sessionFactory.getCurrentSession().delete(person); } } }
PersonService.java
package es.landesoft.mvctesting.service; import java.util.List; import es.landesoft.mvctesting.JavaBeans.Person; public interface PersonService { public void addContact(Person person); public List<Person> listPerson(); public void removePerson(Integer id); }
PersonService.java
package es.landesoft.mvctesting.service; import java.util.List; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import es.landesoft.mvctesting.JavaBeans.Person; import es.landesoft.mvctesting.dao.PersonDAO; @Service public class PersonServiceClass implements PersonService { @Autowired private PersonDAO personDAO; @Transactional public void addContact(Person person) { personDAO.addContact(person); } @Transactional public List<Person> listPerson() { return personDAO.listPersons(); } @Transactional public void removePerson(Integer id) { personDAO.removePerson(id); } }
I am getting this stacktrace error:
SEVERE: Servlet.service() for servlet [appServlet] in context with path [/mvctesting] threw exception [Request processing failed; nested exception is org.springframework.transaction.CannotCreateTransactionException: Could not open Hibernate Session for transaction; nested exception is java.lang.UnsupportedOperationException] with root cause
java.lang.UnsupportedOperationException
at org.apache.commons.dbcp.PoolingDataSource.getConnection(PoolingDataSource.java:136)
at org.apache.commons.dbcp.BasicDataSource.getConnection(BasicDataSource.java:447)
at org.hibernate.service.jdbc.connections.internal.DatasourceConnectionProviderImpl.getConnection(DatasourceConnectionProviderImpl.java:141)
at org.hibernate.internal.AbstractSessionImpl$NonContextualJdbcConnectionAccess.obtainConnection(AbstractSessionImpl.java:292)
at org.hibernate.engine.jdbc.internal.LogicalConnectionImpl.obtainConnection(LogicalConnectionImpl.java:214)
at org.hibernate.engine.jdbc.internal.LogicalConnectionImpl.getConnection(LogicalConnectionImpl.java:157)
at org.hibernate.internal.SessionImpl.connection(SessionImpl.java:550)
at org.springframework.orm.hibernate4.HibernateTransactionManager.doBegin(HibernateTransactionManager.java:354)
at org.springframework.transaction.support.AbstractPlatformTransactionManager.getTransaction(AbstractPlatformTransactionManager.java:371)
at org.springframework.transaction.interceptor.TransactionAspectSupport.createTransactionIfNecessary(TransactionAspectSupport.java:335)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:105)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:202)
at com.sun.proxy.$Proxy30.listPerson(Unknown Source)
at es.landesoft.mvctesting.PersonController.getPersonJson(PersonController.java:60)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.springframework.web.method.support.InvocableHandlerMethod.invoke(InvocableHandlerMethod.java:213)
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:126)
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:96)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:617)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:578)
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:80)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:923)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:852)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:882)
at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:778)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:621)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:728)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:305)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:51)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:222)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:123)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:502)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:171)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:100)
at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:953)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:408)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1041)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:603)
at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:310)
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
In addition, I would be glad if someone can give me some tips to help me organize the xml config files. I am .NET developer and all this maven + xml configurations are something new for me.
Thanks
My solution was changing the bean class in Datasource from:
to the spring Framework class:
I have the feeling you're using a version of commons-dbcp which is not compatible with the version of hibernate you're using... or that you have 2 versions of the commons-dbcp in your classpath.
Why?
Looking at the code from org.apache.commons.dbcp.PoolingDataSource, you can see that the method
getConnetion(String uname, String passwd)
only throws an exception (in the version in the link, the line is 127 rather than 136).And from org.apache.commons.dbcp.BasicDataSource, you can see that it never calls
PoolingDataSource.getConnection(username, password)
solution