I have a problem with a controller and a service injection. In Junit test, it is working all data are added in database and no errors return by my test junit. But when I inject the Service in the Controller, the system return a null object instead instantiation :
My service :
package mypackage.services
public interface ExampleService {
public abstract String helloWorld();
}
package mypackage.services;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Service;
#Service("exampleService")
#Scope("singleton")
public class ExampleServiceImpl implements ExampleService {
#Override
public String helloWorld(){
return "Hello World !";
}
}
My Controller:
package mypackage.controller;
import javax.servlet.http.HttpServletRequest;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.servlet.ModelAndView;
#Controller
#RequestMapping("/planning")
public class PlanningController {
#Autowired
public ExampleService exampleService;
#RequestMapping(method = RequestMethod.GET)
public final ModelAndView planning(final HttpServletRequest request) {
exampleService.helloWorld();
final ModelAndView mav = new ModelAndView("planning", "tasks", "tasks");
return mav;
}
}
Spring-Servlet.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:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx" xmlns:jee="http://www.springframework.org/schema/jee"
xmlns:jpa="http://www.springframework.org/schema/data/jpa"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.1.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-3.1.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.1.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.1.xsd
http://www.springframework.org/schema/jee
http://www.springframework.org/schema/jee/spring-jee-3.1.xsd
http://www.springframework.org/schema/data/jpa
http://www.springframework.org/schema/data/jpa/spring-jpa.xsd">
<!-- Use #Component annotations for bean definitions -->
<context:component-scan base-package="mypackage.services" />
<context:component-scan base-package="mypackage.controller" />
<!-- Use #Controller annotations for MVC controller definitions -->
<mvc:annotation-driven />
<aop:aspectj-autoproxy proxy-target-class="true" />
<!-- View resolver -->
<bean
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/" />
<property name="suffix" value=".jsp" />
</bean>
<bean
class="org.springframework.web.servlet.view.ContentNegotiatingViewResolver">
<property name="order" value="1" />
<property name="mediaTypes">
<map>
<entry key="json" value="application/json" />
</map>
</property>
<property name="defaultViews">
<list>
<!-- Renders JSON View -->
<bean
class="org.springframework.web.servlet.view.json.MappingJacksonJsonView" />
</list>
</property>
</bean>
<mvc:interceptors>
<!-- Resolve the device that originated the web request -->
<bean
class="org.springframework.mobile.device.DeviceResolverHandlerInterceptor" />
</mvc:interceptors>
<jee:jndi-lookup id="dataSource" jndi-name="java:comp/env/jdbc/myDatasource" />
<tx:annotation-driven transaction-manager="transactionManager" />
<bean id="entityManagerFactory"
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="persistenceUnitName" value="myPU" />
<property name="dataSource" ref="dataSource" />
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
<property name="showSql" value="true" />
<property name="database" value="ORACLE" />
</bean>
</property>
<property name="jpaProperties">
<props>
<prop key="hibernate.show_sql">true</prop>
<prop key="hibernate.format_sql">true</prop>
<prop key="hibernate.dialect">org.hibernate.dialect.OracleDialect</prop>
<prop key="hibernate.hbm2ddl.auto">create</prop>
<prop key="hibernate.c3p0.maxSize">1</prop>
<prop key="hibernate.c3p0.minSize">1</prop>
<prop key="hibernate.c3p0.acquireIncrement">1</prop>
<prop key="hibernate.c3p0.idleTestPeriod">300</prop>
<prop key="hibernate.c3p0.maxStatements">0</prop>
<prop key="hibernate.c3p0.timeout">1800</prop>
<prop key="hibernate.c3p0.checkoutTimeout">0</prop>
<prop key="hibernate.c3p0.preferredTestQuery">SELECT * FROM dual</prop>
</props>
</property>
</bean>
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory" />
</bean>
and my web.xml
<?xml version="1.0" encoding="UTF-8"?>
<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">
<display-name>Archetype Created Web Application</display-name>
<servlet>
<servlet-name>spring</servlet-name>
<servlet-class>
org.springframework.web.servlet.DispatcherServlet
</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring-servlet.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>spring</servlet-name>
<url-pattern>*.html</url-pattern>
<url-pattern>*.json</url-pattern>
</servlet-mapping>
<listener>
<listener-class>org.springframework.web.util.Log4jConfigListener</listener-class>
</listener>
<context-param>
<param-name>log4jConfigLocation</param-name>
<param-value>classpath:log4j.xml</param-value>
</context-param>
<filter>
<filter-name>sitemesh</filter-name>
<filter-class>com.opensymphony.sitemesh.webapp.SiteMeshFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>sitemesh</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<resource-ref>
<description>My DataSource Reference</description>
<res-ref-name>jdbc/myDatasource</res-ref-name>
<res-type>javax.sql.DataSource</res-type>
<res-auth>Container</res-auth>
</resource-ref>
<session-config>
<session-timeout>
30
</session-timeout>
</session-config>
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
</web-app>
My test :
...
#Autowired
private ApplicationContext applicationContext;
#Test
public void testPlanning() {
LOGGER.debug("Start testPlanning");
boolean c = applicationContext.containsBean("exampleService");
System.out.println(c);
final PlanningController avc = new PlanningController();
final Object mav = avc.planning(request);
Assert.assertEquals(200, response.getStatus());
Assert.assertTrue(mav instanceof ModelAndView);
ModelAndViewAssert.assertViewName((ModelAndView) mav, "planning");
final BindingResult result = mock(BindingResult.class);
when(result.hasErrors()).thenReturn(true);
LOGGER.debug("End testPlanning");
}
I inherit from a class for my test:
#RunWith(SpringJUnit4ClassRunner.class)
#ContextConfiguration(locations = { "classpath:spring-servlet.xml"})
#TestExecutionListeners({ DependencyInjectionTestExecutionListener.class,
DirtiesContextTestExecutionListener.class,
TransactionalTestExecutionListener.class,
DbUnitTestExecutionListener.class})
public abstract class N2WIAppConfigTest {
private static final Logger LOGGER = LoggerFactory
.getLogger(PlanningControllerTest.class);
#BeforeClass
public static void setUpClass() throws Exception {
// rcarver - setup the jndi context and the datasource
LOGGER.debug("CALL setUpClass");
try {
// Create initial context
System.setProperty(Context.INITIAL_CONTEXT_FACTORY,
"org.apache.naming.java.javaURLContextFactory");
System.setProperty(Context.URL_PKG_PREFIXES, "org.apache.naming");
SimpleNamingContextBuilder builder = SimpleNamingContextBuilder
.emptyActivatedContextBuilder();
// Construct DataSource
ComboPooledDataSource ds = new ComboPooledDataSource();
ds.setDriverClass("oracle.jdbc.driver.OracleDriver");
ds.setJdbcUrl("jdbc:oracle:thin:#localhost:1521:xe");
ds.setUser("nemo2");
ds.setPassword("nemo2");
builder.bind("java:comp/env/jdbc/myDatasource", ds);
builder.activate();
} catch (NamingException ex) {
System.out.println("###################################");
ex.printStackTrace();
}
}
}
I tried in my test load the ApplicationContext and if the service is loaded and it is the case. But in the PlanningController, the service is not injected.
The problem occurs in PlanningController. ExampleService is not injected and don't understand why. Do you have any idea ?
Thanks a lot
For #Autowire to work there are set of things that we need to configure
<context:annotation-config /> in context.xml, You are missing this.
xmlns:context="http://www.springframework.org/schema/context in <beans .. tag
Spring Sterio type annotations like #Controller, #Component, #Service etc.
That's because in this line:
final PlanningController avc = new PlanningController();
you are manually creating a bean instance instead of leaving it to spring, so spring has no means to autowire dependencies.
You should either leave bean creation to the container (spring in this case) or set bean properties yourself.
In your case, you can access spring-managed PlanningController instance using
applicationContext.getBean(PlanningController.class);
Related
i have a problem about Bean creation in xml definer.
When i run the application on server it shows me the first page but when i go to /customer/list it gives me http error - 500
In the tutorial he does nothing else of what i've done.
I can't show you all the .JAR files in the LIB but i have all the dependency he has in the tutorial example.
I am not using Maven, its a normal Dynamic Web Project so i can't just pass to Maven Project.
I've tried to change the Bean name trying to understand if it was a problem of existing object.
This is my Servlet:
package com.luv2code.testdb;
import java.io.IOException;
import java.io.PrintWriter;
import java.sql.Connection;
import java.sql.DriverManager;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* Servlet implementation class TestDbServlet
*/
#WebServlet("/TestDbServlet")
public class TestDbServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
/**
* #see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// setup connection variables
String user = "springstudent";
String pass = "springstudent";
String jdbcUrl = "jdbc:mysql://localhost:3306/web_customer_tracker?useSSL=false&serverTimezone=UTC&allowPublicKeyRetrieval=true";
String driver = "com.mysql.cj.jdbc.Driver";
// get connection to database
try {
PrintWriter out = response.getWriter();
out.println("Connecting to database: " + jdbcUrl);
Class.forName(driver);
Connection myConn = DriverManager.getConnection(jdbcUrl, user, pass);
out.println("SUCCESS!!");
myConn.close();
}
catch (Exception exc) {
exc.printStackTrace();
throw new ServletException(exc);
}
}
This is my CustomerController:
package com.luv2code.springdemo.controller;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
#Controller
#RequestMapping("/customer")
public class CustomerController {
#RequestMapping("/list")
public String listCustomer(Model theModel) {
return "list-customer";
}
}
This is my definer.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:tx="http://www.springframework.org/schema/tx"
xmlns:mvc="http://www.springframework.org/schema/mvc"
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/tx
http://www.springframework.org/schema/tx/spring-tx.xsd">
<!-- Add support for component scanning -->
<context:component-scan base-package="com.luv2code.springdemo" />
<!-- Add support for conversion, formatting and validation support -->
<mvc:annotation-driven/>
<!-- Define Spring MVC view resolver -->
<bean
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/view/" />
<property name="suffix" value=".jsp" />
</bean>
<!-- Step 1: Define Database DataSource / connection pool -->
<bean id="myDataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"
destroy-method="close">
<property name="driverClass" value="com.mysql.cj.jdbc.Driver" />
<property name="jdbcUrl" value="jdbc:mysql://localhost:3306/web_customer_tracker?useSSL=false&serverTimezone=UTC;allowPublicKeyRetrieval=true" />
<property name="user" value="springstudent" />
<property name="password" value="springstudent" />
<!-- these are connection pool properties for C3P0 -->
<property name="initialPoolSize" value="5"/>
<property name="minPoolSize" value="5" />
<property name="maxPoolSize" value="20" />
<property name="maxIdleTime" value="30000" />
</bean>
<!-- Step 2: Setup Hibernate session factory -->
<bean id="sessionFactory"
class="org.springframework.orm.hibernate5.LocalSessionFactoryBean">
<property name="dataSource" ref="myDataSource" />
<property name="packagesToScan" value="com.luv2code.springdemo.entity" />
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
<prop key="hibernate.show_sql">true</prop>
</props>
</property>
</bean>
<!-- Step 3: Setup Hibernate transaction manager -->
<bean id="myTransactionManager"
class="org.springframework.orm.hibernate5.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory"/>
</bean>
<!-- Step 4: Enable configuration of transactional behavior based on annotations -->
<tx:annotation-driven transaction-manager="myTransactionManager" />
<!-- Add support for reading web resources: css, images, js, etc ... -->
<mvc:resources location="/resources/" mapping="/resources/**"></mvc:resources>
</beans>
and this is my web.xml:
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1">
<display-name>spring-mvc-crud-demo</display-name>
<absolute-ordering />
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
<welcome-file>index.html</welcome-file>
</welcome-file-list>
<servlet>
<servlet-name>dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring-mvc-crud-demo-servlet.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>dispatcher</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>
The exception encountered is:
*org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'sessionFactory' defined in ServletContext resource [/WEB-INF/spring-mvc-crud-demo-servlet.xml]: Invocation of init method failed; nested exception is java.lang.NoClassDefFoundError: net/bytebuddy/NamingStrategy$SuffixingRandom$BaseNameResolver *
java.lang.NoClassDefFoundError: Could not initialize class org.hibernate.cfg.Environment *
You could try to add this jar to your project net.bytebuddy.
But I recommend to use maven for these purposes.
This is the controller:
package com.spring.controller;
import java.util.Arrays;
import java.util.List;
import javax.servlet.http.HttpSession;
import org.jboss.logging.annotations.Param;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.servlet.ModelAndView;
import com.spring.DAO.CountryDAO;
import com.spring.DAO.HospitalDAO;
import com.spring.DAO.HospitalSpecialityDAO;
import com.spring.DAO.SpecialityDAO;
import com.spring.VO.HospitalSpecialityVO;
import com.spring.VO.HospitalVO;
import com.spring.VO.SpecialityVO;
#Controller
#RequestMapping("/admin")
public class HospitalController {
#Autowired
CountryDAO country;
#Autowired
HospitalDAO hospital;
#Autowired
SpecialityDAO Speciality;
#Autowired
HospitalSpecialityDAO hospitalSpeciality;
#RequestMapping("/addHospital.html")
public ModelAndView addHospital(HttpSession session) throws Exception {
List<Object> list = this.country.getCountry();
session.setAttribute("list", list);
List<Object> slist = this.Speciality.getSpeciality();
session.setAttribute("slist", slist);
return new ModelAndView("admin/addHospital",
"insertHospitalSpeciality", new HospitalSpecialityVO());
}
}
And this is the URL which I want to map:
/projectname/admin/addHospital.html
This is the web.xml file:
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
version="2.5">
<servlet>
<servlet-name>spring</servlet-name>
<servlet-class>
org.springframework.web.servlet.DispatcherServlet
</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>spring</servlet-name>
<url-pattern>*.html</url-pattern>
</servlet-mapping>
<listener>
<listener-class>
org.springframework.web.context.ContextLoaderListener
</listener-class>
</listener>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring-security.xml</param-value>
</context-param>
<filter>
<filter-name>springSecurityFilterChain</filter-name>
<filter-class>
org.springframework.web.filter.DelegatingFilterProxy
</filter-class>
</filter>
<filter-mapping>
<filter-name>springSecurityFilterChain</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
</web-app>
spring-servlet.xml 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"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd">
<context:component-scan base-package="com.spring" />
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="WEB-INF/view/" />
<property name="suffix" value=".jsp" />
</bean>
<bean id="multipartResolver"
class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<!-- setting maximum upload size -->
<property name="maxUploadSize" value="100000" />
</bean>
<!-- <bean id="dataSource" class="org.apache.commons.dbcp2.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost/healthanalytics"/>
<property name="username" value="root"/>
<property name="password" value="root"/>
</bean> -->
<bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="annotatedClasses">
<list>
<value>com.spring.VO.CityVO</value>
<value>com.spring.VO.ComplainVO</value>
<value>com.spring.VO.CountryVO</value>
<value>com.spring.VO.DiseaseVO</value>
<value>com.spring.VO.DoctorVO</value>
<value>com.spring.VO.FeedbackVO</value>
<value>com.spring.VO.HospitalVO</value>
<value>com.spring.VO.MedicineVO</value>
<value>com.spring.VO.PatientVO</value>
<value>com.spring.VO.StateVO</value>
<value>com.spring.VO.SpecialityVO</value>
<value>com.spring.VO.SymptomVO</value>
<value>com.spring.VO.HospitalSpecialityVO</value>
<value>com.spring.VO.DoctorSpecialityVO</value>
<value>com.spring.VO.DoctorHospitalVO</value>
<value>com.spring.VO.RegistrationVO</value>
<value>com.spring.VO.LoginVO</value>
<!-- <value>com.malhar.model.Login</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.hbm2ddl.auto">update</prop>
<prop key="hibernate.enable_lazy_load_load_trans">true</prop>
</props>
</property>
</bean>
</beans>
But when I call the following url:
http://localhost:8080/health/admin/addHospital.html
I get:
HTTP Status 404 - /health/admin/WEB-INF/view/admin/addHospital.jsp
Here health is the project name.
I am not able to figure out that while getting the result why it is trying to put admin before WEB-INF as shown in error.
Why can't it just get result from /health/WEB-INF/view/admin/addHospital.jsp?
Also if anyone can provide any alternate solution to this it would be much helpful.
In your view resolver configuration, put / before WEB-INF/view/ and for CSS and JavaScript resources use mvc:resources tag to configure resource location and in JSP import them using c:url.
spring-database
<?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:tx="http://www.springframework.org/schema/tx" xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.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">
<context:component-scan base-package="com.hello.hellospring" />
<context:property-placeholder location="classpath:application.properties" />
<tx:annotation-driven transaction-manager="transactionManager" />
<bean id="dataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="${jdbc.driverClassName}" />
<property name="url" value="${jdbc.url}" />
<property name="username" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}" />
</bean>
<bean id="sessionFactory"
class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="packagesToScan">
<list>
<value>com.hello.hellospring.model</value>
</list>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">${hibernate.dialect}</prop>
<prop key="hibernate.show_sql">${hibernate.show_sql}</prop>
<prop key="hibernate.format_sql">${hibernate.format_sql}</prop>
</props>
</property>
</bean>
<bean id="transactionManager"
class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
<bean id="persistenceExceptionTranslationPostProcessor"
class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor" />
</beans>
web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
version="2.5">
<display-name>Spring Security Bcrypt Application</display-name>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
/WEB-INF/applicationContext.xml
/WEB-INF/spring-database.xml
/WEB-INF/spring-security.xml
</param-value>
</context-param>
<!-- Spring MVC -->
<servlet>
<servlet-name>springmvc-dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/mvc-dispatcher-servlet.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>springmvc-dispatcher</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<!-- Spring Security Filter -->
<filter>
<filter-name>springSecurityFilterChain</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
<filter-name>springSecurityFilterChain</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
</web-app>
userDaoImpl.java
package com.hello.hellospring.dao;
import org.hibernate.Criteria;
import org.hibernate.criterion.Restrictions;
import org.springframework.stereotype.Repository;
import com.hello.hellospring.model.User;
#Repository("userDao")
public class UserDaoImpl extends AbstractDao<Integer, User> implements UserDao {
public void save(User user) {
persist(user);
}
public User findById(int id) {
return getByKey(id);
}
public User findBySSO(String sso) {
Criteria crit = createEntityCriteria();
crit.add(Restrictions.eq("ssoId", sso));
return (User) crit.uniqueResult();
}
}
Here is the class where I am getting error:
AbstractDao.java
package com.hello.hellospring.dao;
import java.io.Serializable;
import java.lang.reflect.ParameterizedType;
import org.hibernate.Criteria;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
public abstract class AbstractDao<PK extends Serializable, T> {
private final Class<T> persistentClass;
#SuppressWarnings("unchecked")
public AbstractDao(){
this.persistentClass =(Class<T>) ((ParameterizedType) this.getClass().getGenericSuperclass()).getActualTypeArguments()[1];
}
#Autowired
private SessionFactory sessionFactory;
#Transactional
protected Session getSession(){
return sessionFactory.getCurrentSession();
}
#SuppressWarnings("unchecked")
public T getByKey(PK key) {
return (T) getSession().get(persistentClass, key);
}
public void persist(T entity) {
getSession().persist(entity);
}
public void delete(T entity) {
getSession().delete(entity);
}
protected Criteria createEntityCriteria(){
return getSession().createCriteria(persistentClass);
}
}
I dont know whats wrong with that the issue i got is: please help me to solve this issue. Each time I run this code it is saying that I have some hibernate session issue. thanks :)
try annotating your class or methods with #Transactional. Declarative transaction boundaries will take out this exception.
package com.hello.hellospring.dao;
import org.hibernate.Criteria;
import org.hibernate.criterion.Restrictions;
import org.springframework.stereotype.Repository;
import com.hello.hellospring.model.User;
#Repository("userDao")
#Transactional
public class UserDaoImpl extends AbstractDao<Integer, User> implements UserDao {
public void save(User user) {
persist(user);
}
public User findById(int id) {
return getByKey(id);
}
public User findBySSO(String sso) {
Criteria crit = createEntityCriteria();
crit.add(Restrictions.eq("ssoId", sso));
return (User) crit.uniqueResult();
}
}
You are missing a #Transactional annotation above this class read this http://www.springbyexample.org/examples/hibernate-transaction-annotation-config-code-example.html
This is the mapping part:
#Path("/hello")
public class BookRestController {
#Autowired
BookService service;
#GET
public String getMsg() {
System.out.println("in controller");
List<BookDto> dto=service.loadAll();
System.out.println(dto);
return "dto";
}
}
web.xml code:
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5">
<display-name>springJdbc</display-name>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>index.htm</welcome-file>
<welcome-file>index.jsp</welcome-file>
<welcome-file>default.html</welcome-file>
<welcome-file>default.htm</welcome-file>
<welcome-file>default.jsp</welcome-file>
</welcome-file-list>
<servlet>
<description></description>
<servlet-name>dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>dispatcher</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>jersey-serlvet</servlet-name>
<servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class>
<load-on-startup>2</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>jersey-serlvet</servlet-name>
<url-pattern>/rest/*</url-pattern>
</servlet-mapping>
</web-app>
servlet-dispatcher.xml code:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:p="http://www.springframework.org/schema/p"
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">
<!-- controller package detail -->
<context:component-scan base-package="com.app.controller,com.app.service,com.app.dao.hib" />
<!-- -->
<mvc:annotation-driven/>
<!-- -->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver" p:maxUploadSize="1500000"/>
<!-- -->
<mvc:resources mapping="/static/**" location="/static/" />
<!-- view resolver -->
<bean id="viewResolver1" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix">
<value>/WEB-INF/jsps/</value>
</property>
<property name="suffix">
<value>.jsp</value>
</property>
</bean>
<!-- creating connection detail of hibernate (connection pooling) -->
<bean id="myDataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/db1"/>
<property name="username" value="root"/>
<property name="password" value="root"/>
</bean>
<!-- Hibernate mapping and configuration file details (Session factory details) -->
<bean id="mySessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="dataSource" ref="myDataSource" />
<property name="annotatedClasses">
<list>
<value>com.app.entity.BookEntity</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.hbm2ddl.auto">create</prop> -->
</props>
</property>
</bean>
<tx:annotation-driven transaction-manager="transactionManager"/>
<bean id="transactionManager"
class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<property name="sessionFactory" ref="mySessionFactory" />
</bean>
</beans>
It's giving null pointer exception on service or anything I am using as autowired i.e it's having problems autowiring. Can anyone help with this?I guess i am missing something which is used to implement restFull service coz the application is working fine with simple spring application
Interface :
public interface BookService {
}
Class which implements interface BookService:
#Service
public class BookServiceImpl implements BookService {
}
To autowire BookServiceImpl class, you have to put #Autowired annotation on interface name in BookRestController class and #Controller annotation on your controller class:
#Controller
public class BookRestController {
#Autowired
private BookService bookService;
}
also you have to take care of configuration, like for component scanning you have to add following line in your spring configuration file. Put
<context:component-scan base-package="com.org.dao"/>
in spring configuration xml and change com.org.dao to your package name where dao files placed in application.
This is answered in this thread - Spring DI - Autowired property is null in a REST service
Essentially Jersey doesn't automatically do Spring autowiring for you. You need to get the Spring stuff to happen with the Jersey servlet object.
I have been struggling to make all of this work since days now and don't know what to do. I believe I went through every single post on the subject here on SO and went through douzens of tutorials...
Here is the message I am having at this time:
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'fruitController': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire method: public void com.controller.FruitController.setFruitManager(com.service.FruitManager); nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No matching bean of type [com.service.FruitManager] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {}
I have been able to solve this error in the past, but only to have a new one "No session found for current thread". When not having this one, I got some problem with my Assembler and UserDetailsServiceImpl bean not being recognized in my spring-security.xml file...
I do not think the problem(s) come from my code, I just can't get to set my config files properly and I am probably missing something here.
Here are the config files:
web.xml:
<web-app id="WebApp_ID" version="2.4"
xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee
http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
<display-name>Spring MVC Application</display-name>
<!-- Spring MVC -->
<servlet>
<servlet-name>mvc-dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>mvc-dispatcher</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
/WEB-INF/mvc-dispatcher-servlet.xml,
/WEB-INF/spring-security.xml
</param-value>
</context-param>
<!-- Spring Security -->
<filter>
<filter-name>springSecurityFilterChain</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
<filter-name>springSecurityFilterChain</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
</web-app>
applicationContext.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: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:mvc="http://www.springframework.org/schema/mvc"
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/tx
http://www.springframework.org/schema/tx/spring-tx-3.0.xsd">
<context:annotation-config/>
<!-- Load everything except #Controllers -->
<context:component-scan base-package="com">
<context:exclude-filter expression="org.springframework.stereotype.Controller"
type="annotation" />
</context:component-scan>
<tx:annotation-driven transaction-manager="transactionManager" />
<tx:advice id="txAdvice">
<tx:attributes>
<tx:method name="save*" />
<tx:method name="*" read-only="false" />
</tx:attributes>
</tx:advice>
<bean id="transactionManager"
class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
<bean id="sessionFactory"
class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="annotatedClasses">
<list>
<value>com.dao.HibernateFruitDAO</value>
</list>
</property>
<property name="packagesToScan">
<list>
<value>com.service</value>
<value>com.controller</value>
</list>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</prop>
<prop key="hibernate.hbm2ddl.auto">update</prop>
<prop key="hibernate.show_sql">true</prop>
</props>
</property>
</bean>
<bean id="dataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver" />
<property name="url" value="jdbc:mysql://localhost:3306/basename" />
<property name="username" value="xxx" />
<property name="password" value="yyy" />
</bean>
</beans>
mvc-dispatcher-servlet.xml:
<beans xmlns="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"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-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:property-placeholder location="classpath:hibernate.properties" />
<!-- Load #Controllers only -->
<context:component-scan base-package="com.controller"
use-default-filters="false">
<context:include-filter expression="org.springframework.stereotype.Controller"
type="annotation" />
</context:component-scan>
<bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter"></bean>
<bean class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping"></bean>
<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>
<bean id="messageSource"
class="org.springframework.context.support.ResourceBundleMessageSource">
<property name="basenames">
<list>
<value>mymessages</value>
</list>
</property>
</bean>
<bean id="propertyConfigurer"
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations">
<list>
<value>classpath:jdbc.properties</value>
</list>
</property>
</bean>
</beans>
spring-security.xml
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.1.xsd">
<beans:bean id="userDetailsService" class="com.service.UserDetailsServiceImpl">
</beans:bean>
<beans:bean id="assembler" class="com.service.Assembler">
</beans:bean>
<http auto-config='true' use-expressions='true'>
<intercept-url pattern="/login*" access="isAnonymous()" />
<intercept-url pattern="/secure/**" access="hasRole('ROLE_Admin')" />
<logout logout-success-url="/listing.htm" />
<form-login login-page="/login.htm" login-processing-url="/j_spring_security_check"
authentication-failure-url="/login_error.htm" default-target-url="/listing.htm"
always-use-default-target="true" />
</http>
<beans:bean id="com.daoAuthenticationProvider"
class="org.springframework.security.authentication.dao.DaoAuthenticationProvider">
<beans:property name="userDetailsService" ref="userDetailsService" />
</beans:bean>
<beans:bean id="authenticationManager"
class="org.springframework.security.authentication.ProviderManager">
<beans:property name="providers">
<beans:list>
<beans:ref local="com.daoAuthenticationProvider" />
</beans:list>
</beans:property>
</beans:bean>
<authentication-manager>
<authentication-provider user-service-ref="userDetailsService">
<password-encoder hash="plaintext" />
</authentication-provider>
</authentication-manager>
</beans:beans>
FruitController:
package com.controller;
#Controller
public class FruitController{
protected final Log logger = LogFactory.getLog(getClass());
private FruitManager fruitManager;
#Autowired
public void setFruitManager(FruitManager FruitManager) {
this.fruitManager = fruitManager;
}
#RequestMapping(value = "/listing", method = RequestMethod.GET)
public String getFruits(ModelMap model) {
model.addAttribute("fruits", this.fruitManager.getFruits());
return "listing";
}
}
FruitDAO:
public interface FruitDAO {
public List<Fruit> getFruitList();
public List<Fruit> getFruitListByUserId(String userId);
public void saveFruit(Fruitprod);
public void updateFruit(Fruitprod);
public void deleteFruit(int id);
public Fruit getFruitById(int id);
}
HibernateFruitDAO
package com.dao;
#Repository("fruitDao")
public class HibernateFruitDAO implements FruitDAO {
private SessionFactory sessionFactory;
#Autowired
public void setSessionFactory(SessionFactory sessionFactory) {
this.sessionFactory = sessionFactory;
}
public List<Fruit> getList() {
return (List<Fruit>) getSession().createCriteria ( Fruit.class ).list();
}
public List<Fruit> getFruitListByUserId(String userId) {
return (List<Fruit>)sessionFactory.getCurrentSession().createCriteria("from Fruit where userId =?", userId).list();
}
public void saveFruit(Fruit fruit) {
sessionFactory.getCurrentSession().save(fruit);
}
public void updateFruit(Fruit fruit) {
sessionFactory.getCurrentSession().update(fruit);
}
public void deleteFruit(int id) {
Fruit fruit = (Fruit) sessionFactory.getCurrentSession().load(Fruit.class, id);
if (null != fruit) {
sessionFactory.getCurrentSession().delete(fruit);
}
}
public Fruit getFruitById(int id) {
return (Fruit)sessionFactory.getCurrentSession().load(Fruit.class, id);
}
private Session getSession(){
return sessionFactory.getCurrentSession();
}
}
Interface FruitManager:
package com.service;
import java.io.Serializable;
import java.util.List;
import com.domain.Fruit;
public interface FruitManager extends Serializable{
public List<Fruit> getFruits();
public List<Fruit> getFruitsByUserId(String userId);
public void addFruit(Fruit fruit);
public void removeFruit(int id);
public Fruit getFruitById(int id);
public void updateFruit(Fruit fruit);
}
Implementation of FruitManager:
package com.service;
#Repository("fruitManager")
#Transactional
public class SimpleFruitManager implements FruitManager {
/**
*
*/
private static final long serialVersionUID = ...;
#Autowired
private FruitDAO fruitDao;
public List<Fruit> getFruits() {
return fruitDao.getFruitList();
}
public List<Fruit> getFruitsByUserId(String userId){
return fruitDao.getFruitListByUserId(userId);
}
public void setFruitDao(FruitDAO fruitDao) {
this.fruitDao = fruitDao;
}
public void addFruit(Fruit fruit) {
fruitDao.saveFruit(fruit);
}
public void removeFruit(int id) {
fruitDao.deleteFruit(id);
}
public getFruitById(int id) {
return fruitDao.getFruitById(id);
}
public void updateFruit(Fruit fruit) {
fruitDao.updateFruit(fruit);
}
}
At a glance, it seems you're suffering from a common problem of not understanding how Spring ApplicationContexts fit together to make a web application. See my other answer to exactly the same problem to see if it clears things up:
Declaring Spring Bean in Parent Context vs Child Context
You may also be enlightened by this answer on a similar topic, which links to my previously mentioned answer as well as one other:
Spring XML file configuration hierarchy help/explanation
A couple brief tips to get you headed in the right direction...
By convention, Spring's ContextLoaderListener loads beans from WEB-INF/applicationContext.xml to create the root application context. When you override the default, as you're doing, that file is no longer loaded.
Tip #1: stick with the conventional behavior. It'll make your life simpler.
Also by convention, starting up a Spring DispatcherServlet loads beans from WEB-INF/<servlet name>-context.xml to create the context used to configure the dispatcher servlet. This context becomes a child of the root context.
Tip #2: see tip #1
So you see, you're presently over-configuring things. Read the linked answers and the reference materials linked therein. Learn to work with Spring instead of against it.
In your web.xml file, the applicationContext.xml is never get loaded. You should put it location in context-param. Put the location of mvc-dispatcher-servlet.xml (containing controller related bean) as init-param for DispatcherServlet instead:
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/mvc-dispatcher-servlet.xml</param-value>
</init-param>
I think you must to use this in the DaoImpl to get the session:
#Autowired
private SessionFactory sessionFactory;