TransactionRequiredException in spring webmvc framework - java

It's many similar, but not the same issues, so I couldn't find a solution for this one.
I have Spring + JPA(Hibernate) web-application.
Context configuration (data-context.xml):
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:jdbc="http://www.springframework.org/schema/jdbc"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.2.xsd
http://www.springframework.org/schema/jdbc
http://www.springframework.org/schema/jdbc/spring-jdbc-3.2.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.2.xsd">
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="org.postgresql.Driver"/>
<property name="url" value="jdbc:postgresql://localhost:5432/db"/>
<property name="username" value="postgres"/>
<property name="password" value="1234"/>
</bean>
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="emf"/>
</bean>
<tx:annotation-driven transaction-manager="transactionManager" />
<bean id="emf" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="dataSource" ref="dataSource"/>
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"/>
</property>
<property name="packagesToScan" value="com.myapp.mvc.logic.domain"/>
<property name="jpaProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.PostgreSQLDialect</prop>
<prop key="hibernate.max_fetch_depth">3</prop>
<prop key="hibernate.jdbc.fetch_size">50</prop>
<prop key="hibernate.jdbc.batch_size">10</prop>
<prop key="hibernate.show_sql">true</prop>
</props>
</property>
</bean>
<bean id="validator" class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean"/>
<context:annotation-config/>
<context:component-scan base-package="com.myapp.mvc.logic" />
DispetcherServlet configuration (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:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:security="http://www.springframework.org/schema/security"
xsi:schemaLocation="http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.2.xsd
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security-3.1.xsd
">
<annotation-driven validator="validator"/>
<resources mapping="/resources/**" location="/resources/" />
<default-servlet-handler/>
<beans:bean class="org.springframework.web.servlet.view.UrlBasedViewResolver" id="tilesViewResolver">
<beans:property name="viewClass" value="org.springframework.web.servlet.view.tiles3.TilesView"/>
</beans:bean>
<beans:bean class="org.springframework.web.servlet.view.tiles3.TilesConfigurer" id="tilesConfigurer">
<beans:property name="definitions">
<beans:list>
<beans:value>/WEB-INF/layouts/layouts.xml</beans:value>
<beans:value>/WEB-INF/views/**/views.xml</beans:value>
</beans:list>
</beans:property>
</beans:bean>
<interceptors>
<beans:bean class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor" p:paramName="lang"/>
</interceptors>
<beans:bean class="org.springframework.context.support.ReloadableResourceBundleMessageSource"
id="messageSource"
p:basenames="classpath:META-INF/i18n/application, classpath:META-INF/i18n/validation_messages"
/>
<beans:bean class="org.springframework.web.servlet.i18n.CookieLocaleResolver"
id="localeResolver"
p:cookieName="locale"/>
<beans:bean id="validator" class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean">
<beans:property name="validationMessageSource" ref="messageSource"/>
</beans:bean>
<context:component-scan base-package="com.myapp.mvc" />
Controller:
#RequestMapping("/users")
#Controller
public class BankAccountCatalogController {
#Inject
private Functions functions;
#RequestMapping(value="/update", method = RequestMethod.POST)
public String catalogBankAccountUpdate(Model uiModel) {
functions.addUser();
return "employee_cabinet/catalog_bank_account";
}
}
Functions.class:
#Service("functions")
#Repository
#Transactional
public class Functions {
#PersistenceContext
private EntityManager em;
#Transactional
public void addUser() {
User user = new User();
user.setFirstName("John");
user.setLastName("John");
user.setMiddleName("John");
user.setEmail("John#gmail.com");
user.setPhone(null);
user.setMd5Password("1234");
em.persist(user);
em.flush();
}
}
When I activate the controller, in em.flush(); line I get an error:
javax.persistence.TransactionRequiredException: no transaction is in progress
On some reason transaction don't active in addUser() function. I tried run function in JUnit environment - it works fine.
Any ideas?

Try removing the EntityManager from the controller and specifying the method as transactional on the controller.
#RequestMapping("/users")
#Controller
public class BankAccountCatalogController {
#Inject
private Functions functions;
#RequestMapping(value="/update", method = RequestMethod.POST)
#Transactional
public String catalogBankAccountUpdate(Model uiModel) {
functions.addUser();
return "employee_cabinet/catalog_bank_account";
}
}
Also make sure the Functions class is specified in the packages you are component scanning, which is com.dominform.mvc.logic.
<context:component-scan base-package="com.dominform.mvc.logic" />

Solved. It was wrong configuration of DispetcherServlet.
Instead of
<context:component-scan base-package="com.myapp.mvc" />
in servlet-context.xml, I wrote
<context:component-scan base-package="com.myapp.mvc.web.controller" />
and it works.
Helpful topic: Spring #Transactional - javax.persistence.TransactionRequiredException

Related

autowire by name not working spring MVC

web.xml
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<servlet>
<servlet-name>spring-mvc</servlet-name>
<servlet-class>
org.springframework.web.servlet.DispatcherServlet
</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
my spring-mvc-servlet.xml
<context:component-scan base-package="org.app.controller" />
<mvc:resources mapping="/resources/**" location="/WEB-INF/resources/" />
<mvc:annotation-driven />
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix">
<value>/WEB-INF/pages/</value>
</property>
<property name="suffix">
<value>.jsp</value>
</property>
</bean>
my controller: Just for illustration
#Controller
public class HomeController {
LoginService loginService;
#RequestMapping(value = "/", method = RequestMethod.GET)
public String login(Model model) {
loginService.checkLoginDetails(new LoginDetails("Svn", 1));
return "login";
}
AppplicationContext.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx" xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.0.xsd">
<!-- <context:annotation-config /> -->
<bean id="dataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver"></property>
<property name="url" value="jdbc:mysql://localhost:3306/test"></property>
<property name="username" value="root"></property>
<property name="password" value=""></property>
</bean>
<bean class="org.app.controller.HomeController" autowire="byName"></bean>
<bean id="loginDAO" class="org.app.DAOImpl.LoginDAOImpl" autowire="byName"></bean>
<bean id="loginService" class="org.app.DAOServiceImpl.LoginServiceImpl" autowire="byName"></bean>
<bean id="employeeDAO" class="org.app.DAOImpl.EmployeeDAOImpl" autowire="byName"></bean>
<bean id="employeeService" class="org.app.DAOServiceImpl.EmployeeDAOServiceImpl" autowire="byName"></bean>
<bean id="sessionFactory"
class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource"></property>
<property name="annotatedClasses">
<list>
<value>org.app.entity.Employee</value>
<value>org.app.entity.LoginDetails</value>
</list>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
<prop key="hibernate.hbm2ddl.auto">create</prop>
<prop key="hibernate.show_sql">true</prop>
</props>
</property>
</bean>
<!-- <context:component-scan base-package="org.infy"> <context:exclude-filter
expression="org.springframework.stereotype.Controller" type="annotation"
/> </context:component-scan> -->
<tx:annotation-driven />
<bean id="transactionManager"
class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
</beans>
LoginServiceImpl
public class LoginServiceImpl implements LoginService{
LoginDAO loginDAO;
#Override
#Transactional
public boolean checkLoginDetails(LoginDetails loginDetails) {
return loginDAO.checkLoginDetails(loginDetails);
}
}
Problem: My LoginDAO is null. Spring is not able to instantiate it's object using auto-wiring when done without annotation, however, works fine when I use it with annotation along with appropriate changes in ApplicationContext.xml.
My LoginService bean is getting instantiated by the component scan of dispatcher servlet context. Now when instantiating LoginServiceImpl spring should look into RootApplication context for other bean definitions however it doesn't.
I don't understand why does this happen when using #autowire with or enabling the component scan. it works fine then why not without annotation.
I'm also not sure what I'm trying to do. I was playing with Spring MVC and got stuck on this.
Please update your ApplicationContext.xml
<bean id="loginService" class="org.app.DAOServiceImpl.LoginServiceImpl" autowire="byName">
<property name="loginDAO" ref="loginDAO"> </property>
</bean>
Same thing goes for the EmployeeService and your controller as well.
<bean class="org.app.controller.HomeController" autowire="byName">
<property name="loginService" ref="loginService"> </property>
</bean>
<bean id="employeeService" class="org.app.DAOServiceImpl.EmployeeDAOServiceImpl" autowire="byName">
<property name="employeeDAO" ref="employeeDAO"> </property>
</bean>
Though I still recommend you to use annotations.
In AppplicationContext.xml you need to specify injected dependencies for your beans as element inside

HikariCP too many Connections with jooq

When using jooq and HikariCP DataSource (Autowired) in a Spring Restful API i get the problem, that jooq is somehow not releasing the DataSource.
Some Code:
#Autowired
private DataSource dataSource;
//Further down
DSLContext create = DSL.using(dataSource, SQLDialect.MYSQL);
After using this repository/call two or three times i have too many connections open.
My dispatcher-servlet.xml:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:security="http://www.springframework.org/schema/security"
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/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security.xsd">
<context:component-scan base-package="com.rh" />
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<property name="maxUploadSize" value="20971520"/> <!-- 20 MB -->
</bean>
<context:property-placeholder location="classpath:database/database.properties"/>
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="dataSource"></property>
</bean>
<bean id="hikariConfig" class="com.zaxxer.hikari.HikariConfig">
<property name="poolName" value="springHikariCP" />
<property name="connectionTestQuery" value="SELECT 1" />
<property name="dataSourceClassName" value="${jdbc.driver}" />
<property name="maximumPoolSize" value="20" />
<property name="idleTimeout" value="20" />
<property name="dataSourceProperties">
<props>
<prop key="url">${jdbc.url}</prop>
<prop key="user">${jdbc.username}</prop>
<prop key="password">${jdbc.password}</prop>
<prop key="prepStmtCacheSize">50</prop>
<prop key="prepStmtCacheSqlLimit">50</prop>
<prop key="cachePrepStmts">true</prop>
<prop key="useServerPrepStmts">true</prop>
</props>
</property>
</bean>
<!-- HikariCP configuration -->
<bean id="dataSource" class="com.zaxxer.hikari.HikariDataSource" destroy-method="close">
<constructor-arg ref="hikariConfig" />
</bean>
<bean id="passwordEncoder" class="org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder">
<!--<beans:constructor-arg value="256" />-->
<!--<beans:property name="iterations" value="1000" />-->
</bean>
<!--Different providers-->
<bean id="cloudinaryProvider" class="com.rh.bean.CloudinaryProvider"></bean>
<bean id="s3Provider" class="com.rh.bean.S3Provider"></bean>
<bean id="objectMapper" class="org.springframework.http.converter.json.Jackson2ObjectMapperFactoryBean" autowire="no">
<property name="propertyNamingStrategy" value="CAMEL_CASE_TO_LOWER_CASE_WITH_UNDERSCORES" />
</bean>
<mvc:annotation-driven>
<mvc:path-matching suffix-pattern="false" trailing-slash="false" />
<mvc:argument-resolvers>
<bean class="com.rh.util.CurrentUserHandlerMethodArgumentResolver"/>
</mvc:argument-resolvers>
<mvc:message-converters register-defaults="true">
<bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
<property name="objectMapper">
<ref bean="objectMapper" />
</property>
</bean>
</mvc:message-converters>
</mvc:annotation-driven>
<security:global-method-security pre-post-annotations="enabled" secured-annotations="enabled"></security:global-method-security>
</beans>
Ok i fixed the problem:
#Autowired
private DataSource dataSource;
//Further down
Connection con=dataSource.getConnection();
DSLContext create = DSL.using(con, SQLDialect.MYSQL);
//Execute code here
con.close();
So instead of directly using the DataSource i used a connection and released it.

Spring Hibernate session issue

Hi I'm having a problem setting up hibernate on spring. I was able to make it work but it creates a lot of session on the database. From What i have notice it creates session for every bean on my spring.xml. Since I have 6 beans declared I also have 6 session on the database on application start Here is my code
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"
xmlns:tx="http://www.springframework.org/schema/tx"
>
<!-- Uncomment and add your base-package here: <context:component-scan base-package="org.springframework.samples.service"/> -->
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
destroy-method="close">
<property name="driverClassName" value="oracle.jdbc.driver.OracleDriver" />
<property name="url" value="jdbc:oracle:thin:" />
<property name="username" value="Use" />
<property name="password" value="Pass" />
</bean>
<!-- Hibernate 4 SessionFactory Bean definition -->
<bean id="hibernate4AnnotatedSessionFactory"
class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="packagesToScan" value="com.model" />
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.Oracle10gDialect</prop>
<prop key="hibernate.current_session_context_class">thread</prop>
<!-- <prop key="hibernate.current_session_context_class">managed</prop> -->
<prop key="hibernate.show_sql">true</prop>
<prop key="format_sql">true</prop>
</props>
</property>
</bean>
<bean id="PDao" class="com.PDaoImpl">
<property name="sessionFactory" ref="hibernate4AnnotatedSessionFactory" />
</bean>
<bean id="PService" class="com.PServiceImpl">
<property name="pDao" ref="PDao" />
</bean>
<bean id="MNDao" class="com.MNDaoImpl">
<property name="sessionFactory" ref="hibernate4AnnotatedSessionFactory" />
</bean>
<bean id="MNService" class="com.MNServiceImpl">
<property name="MNDao" ref="MNDao" />
</bean>
<bean id="SWDao" class="com.SWDaoImpl">
<property name="sessionFactory" ref="hibernate4AnnotatedSessionFactory" />
</bean>
<bean id="SWService" class="com.SWServiceImpl">
<property name="SWDao" ref="SWDao" />
</bean>
You need to use transactionManager to manage session for you.
Add the following lines of code to your spring.xml
....
<tx:annotation-driven transaction-manager="transactionManager" />
<bean id="transactionManager"
class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<property name="sessionFactory" ref="yourSessionFactory" />
</bean>
....
Then you have to annotate your service impl classes #Transactional("transactionManager") to make transactionManager managing transactions through session
#Transactional("transactionManager")
public class PServiceImpl implements PServiceImpl{
....
Just an advice you can replace XML config for the DI by annotations to make it easy
in spring.xml, remove all your beans declarations (xxservice and xxxdao) and replace them by: <context:component-scan base-package="put here the package where your services and daos are lacated" />
your service must look like this :
#Service
#Transactional("transactionManager")
public class XXXServiceImpl implements XXXService{
#Autowired
private XXXDAO xxxDAO;
...
}
And your dao must look like :
#Repository
public class XXXDAOImpl implements XXXDAO {
#Autowired
private SessionFactory sessionFactory;
...
}
One more thing, add the tx schema in your file config header, your spring.xml should look like this :
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
xmlns:tx="http://www.springframework.org/schema/tx"
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/tx
http://www.springframework.org/schema/tx/spring-tx.xsd">

Testing dao with junit in Spring MVC project

I've just started my journey with Spring, so I'm a newbie.
I'm trying to write tests to DAO.
When I run tests the stack trace returns:
Caused by: org.springframework.beans.factory.BeanCreationException: Could not autowire field: private pl.com.tt.persistence.TestEntityDaoJPA pl.com.tt.tests.TestPersistenceDAO.testEntityDaoJPA; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No matching bean of type [pl.com.tt.persistence.TestEntityDaoJPA] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {#org.springframework.beans.factory.annotation.Autowired(required=true)}
It looks like I shouldn't use #Autowired above TestEntityDAO implementation. When I delete #Autowire annotation stack trace returns error with invocation method testEntityDaoJPA.getAll(sql).
This is my test class:
#RunWith(SpringJUnit4ClassRunner.class)
#ContextConfiguration
public class TestPersistenceDAO extends AbstractTransactionalJUnit4SpringContextTests{
#Autowired
private TestEntityDaoJPA testEntityDaoJPA;
#Test
public void testDAO(){
String sql = "SELECT r FROM TestEntity r WHERE ROWNUM<200";
testEntityDaoJPA.getAll(sql);
}
}
My DAO class:
#Component
public class TestEntityDaoJPA implements TestEntityDao {
#Autowired
#PersistenceContext private EntityManager em;
#Transactional
public List<TestEntity> getAll(String sql){
TypedQuery<TestEntity> q = em.createQuery(sql, TestEntity.class );
List<TestEntity> result = q.getResultList();
return result;
}
}
XML context file:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:jdbc="http://www.springframework.org/schema/jdbc"
xmlns:tx="http://www.springframework.org/schema/tx"
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/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd">
<context:component-scan base-package="pl.com.tt.tests" />
<context:annotation-config/>
<tx:annotation-driven/>
<bean id="dataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="oracle.jdbc.driver.OracleDriver" />
<property name="url"
value="jdbc:oracle:thin:#192.168.80.128:1521:orcl" />
<property name="username" value="findfnorg" />
<property name="password" value="findfnorg" />
</bean>
<bean id="entityManagerFactory"
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="packagesToScan" value="pl.com.tt.tests" />
<property name="persistenceProviderClass"
value="org.hibernate.ejb.HibernatePersistence" />
<property name="loadTimeWeaver">
<bean
class="org.springframework.instrument.classloading.InstrumentationLoadTimeWeaver" />
</property>
<property name="jpaProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.Oracle10gDialect
</prop>
<prop key="hibernate.show_sql">true</prop>
</props>
</property>
</bean>
<bean id="transactionManager"
class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory" />
</bean>
</beans>
Your package is not scanned by spring.
You indicate:
<context:component-scan base-package="pl.com.tt.tests" />
But TestEntityDaoJPA is in pl.com.tt.persistence. So this package is not scanned and no bean is created.
Try to change to:
<context:component-scan base-package="pl.com.tt.tests,pl.com.tt.persistence" />

Why is my spring bean which is injected properly on server start up, null when I post my form to the controller?

Why is my spring bean (loginInfoDAO) which is injected properly on server start up, null when I post my form to the controller? I have stepped through the setters on start up and they are injecting properly. However, I run the get method and then the post method and the values that were injected are null. Why would this happen?
Controller
#Controller
#RequestMapping("/login")
public class LoginController extends BaseController{
private LoginInfoDAO loginInfoDAO;
public void setLoginInfoDAO(LoginInfoDAO loginInfoDAO) {
this.loginInfoDAO = loginInfoDAO;
}
#RequestMapping(method=RequestMethod.GET)
public ModelAndView getLogin(#ModelAttribute("user") final User ur) {
ModelAndView mav = new ModelAndView("/login/login");
return mav;
}
#RequestMapping(method=RequestMethod.POST)
public ModelAndView login(#ModelAttribute("user") final User ur) {
loginInfoDAO.login(ur);
ModelAndView mav = new ModelAndView();
return mav;
}
}
application-context.xml
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd">
<bean id="myDataSource"
class="org.apache.tomcat.dbcp.dbcp.BasicDataSource">
<property name="driverClassName">
<value>com.mysql.jdbc.Driver</value>
</property>
<property name="url">
<value>jdbc:mysql://localhost/databasename</value>
</property>
<property name="username">
<value>databaseusername</value>
</property>
<property name="password">
<value>databasepassword</value>
</property>
<!-- Disable the second-level cache -->
<!-- Echo all executed SQL to stdout -->
</bean>
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
<property name="dataSource" ref="myDataSource" />
<property name="annotatedClasses">
<list>
<value>com.projectname.model.LoginInfo</value>
<value>com.projectname.model.User</value>
</list>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
<prop key="hibernate.show_sql">true</prop>
<prop key="hibernate.show_sql">true</prop>
</props>
</property>
</bean>
<bean id="myLoginInfoDAO" class="com.projectname.dao.LoginInfoDAOImpl">
<property name="sessionFactory" ref="sessionFactory"/>
</bean>
<bean name="/login" class="com.projectname.controllers.LoginController" >
<property name="loginInfoDAO" ref="myLoginInfoDAO" />
</bean>
</beans>
spring-servlet.xml
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd">
<context:annotation-config />
<context:component-scan
base-package="com.projectname" />
<bean id="viewResolver"
class="org.springframework.web.servlet.view.UrlBasedViewResolver">
<property name="viewClass"
value="org.springframework.web.servlet.view.JstlView" />
<property name="prefix" value="/WEB-INF/views/" />
<property name="suffix" value=".jsp" />
</bean>
<bean id="messageSource" class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
<property name="basenames">
<value>/WEB-INF/messages/messages</value>
</property>
<property name="cacheSeconds" value="60" />
<property name="defaultEncoding" value="UTF-8" />
</bean>
</beans>
Add #Autowired for loginInfoDAO since you are using context:annotation-config.
#Autowired
private LoginInfoDAO loginInfoDAO;
Then remove the following entries from your context xml (since they are driven with the annotation here).
<bean id="myLoginInfoDAO" class="com.projectname.dao.LoginInfoDAOImpl">
<property name="sessionFactory" ref="sessionFactory"/>
</bean>
<bean name="/login" class="com.projectname.controllers.LoginController" >
<property name="loginInfoDAO" ref="myLoginInfoDAO" />
</bean>
This should get you going.

Categories