error working with spring restful service - spring

i am new to spring restful service and i want to get the result in differnt format when i type the below url-----
localhost:7001/SpringRestService/restful/methodName/ALL/ALL/ALL/ALL.xml
localhost:7001/SpringRestService/restful/methodName/ALL/ALL/ALL/ALL.json
localhost:7001/SpringRestService/restful/methodName/ALL/ALL/ALL/ALL.pdf
but i am getting the below error when i start my server----
<Servlet: "SpringRest" failed to preload on startup in Web application: "SpringRestService".
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.web.servlet.view.ContentNegotiatingViewResolver#0' defined in ServletContext resource [/WEB-INF/SpringRest-servlet.xml]: Cannot create inner bean 'org.springframework.web.servlet.view.UrlBasedViewResolver#20e0f98' of type [org.springframework.web.servlet.view.UrlBasedViewResolver] while setting bean property 'viewResolvers' with key [0]; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.web.servlet.view.UrlBasedViewResolver#20e0f98' defined in ServletContext resource [/WEB-INF/SpringRest-servlet.xml]: Initialization of bean failed; nested exception is java.lang.IllegalArgumentException: Property 'viewClass' is required
at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveInnerBean(BeanDefinitionValueResolver.java:282)
at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveValueIfNecessary(BeanDefinitionValueResolver.java:121)
at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveManagedList(BeanDefinitionValueResolver.java:353)
at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveValueIfNecessary(BeanDefinitionValueResolver.java:154)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyPropertyValues(AbstractAutowireCapableBeanFactory.java:1391)
Truncated. see log file for complete stacktrace
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.web.servlet.view.UrlBasedViewResolver#20e0f98' defined in ServletContext resource [/WEB-INF/SpringRest-servlet.xml]: Initialization of bean failed; nested exception is java.lang.IllegalArgumentException: Property 'viewClass' is required
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:532)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:461)
at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveInnerBean(BeanDefinitionValueResolver.java:271)
at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveValueIfNecessary(BeanDefinitionValueResolver.java:121)
at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveManagedList(BeanDefinitionValueResolver.java:353)
Truncated. see log file for complete stacktrace
java.lang.IllegalArgumentException: Property 'viewClass' is required
-----------------------springRest-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"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
<!-- Specify a view resolver for JSP files-->
<bean id="viewResolvers" class="org.springframework.web.servlet.view.InternalResourceViewResolver"
p:prefix="/WEB-INF/view/" p:suffix=".jsp" />
<bean class="org.springframework.web.servlet.view.ContentNegotiatingViewResolver">
<property name="mediaTypes">
<map>
<entry key="xml" value="application/xml"/>
<entry key="html" value="text/html"/>
</map>
</property>
<property name="viewResolvers">
<list>
<bean class="org.springframework.web.servlet.view.UrlBasedViewResolver"/>
</list>
</property>
<property name="defaultViews">
<list>
<bean class="org.springframework.web.servlet.view.json.MappingJacksonJsonView" />
</list>
</property>
</bean>
</beans>
-----------------------------my controller class------------------------------
below is my controller class
package org.nea.rest.unsr;
import java.util.ArrayList;
import java.util.List;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.nea.ia.services.util.uniserv.UniServGrantInfo;
import org.nea.spring.services.interfaces.uniservs.UniservSearchInterface;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;
#Controller
public class HelloWorldController1 {
#Autowired
UniservSearchInterface uniservService;
public UniservSearchInterface getUniservService() {
return uniservService;
}
public void setUniservService(UniservSearchInterface uniservService) {
this.uniservService = uniservService;
}
protected final Log logger = LogFactory.getLog(getClass());
/* commented
#RequestMapping(value = "/showAllGrants/{userName}/{year}/{status}/{stateId}", method = RequestMethod.GET)
public #ResponseBody
List<UniServGrantInfo> getTextFromURL(#PathVariable("userName") String userName, #PathVariable("year") String year,
#PathVariable("status") String status, #PathVariable("stateId") String stateId) {
List<UniServGrantInfo> grantInfoList = new ArrayList<UniServGrantInfo>();
grantInfoList = uniservService.showAllgrants(userName, year, status, stateId);
return grantInfoList;
}
*/
#RequestMapping(value = "/showAllGrants/{userName}/{year}/{status}/{stateId}", method = RequestMethod.GET)
public ModelAndView getTextFromURL(#PathVariable("userName") String userName, #PathVariable("year") String year,
#PathVariable("status") String status, #PathVariable("stateId") String stateId) {
List<UniServGrantInfo> grantInfoList = new ArrayList<UniServGrantInfo>();
grantInfoList = uniservService.showAllgrants(userName, year, status, stateId);
ModelAndView model = new ModelAndView("index");
//ModelAndView mav = new ModelAndView();
// mav.setViewName("index");
// mav.addObject("sampleContentList", grantInfoList);
return model;
}
}
can anybody help me telling where i am doing wrong or if i am missing any required jar file.

Your configuration for the UrlBasedViewResolver is incomplete. The exception states that the property ‘viewClass‘ is missing. For example a complete configuration:
<bean id="viewResolver" class="org.springframework.web.servlet.view.UrlBasedViewResolver">
<property name="prefix" value="/jsp/"/>
<property name="suffix" value=".jsp"/>
<property name="viewClass"
value="org.springframework.web.servlet.view.JstlView"/>
</bean>

Related

UnsatisfiedDependencyException: Spring MVC project fails to start because of Unsatisfied Dependency

I am trying to start a spring mvc application,
and keep receiving the following error which I cannot solve
org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'customerController': Unsatisfied dependency expressed through field 'customerDAO'; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'customerDAOImpl': Unsatisfied dependency expressed through field 'sessionFactory'; nested exception 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 org.hibernate.MappingException: Could not get constructor for org.hibernate.persister.entity.SingleTableEntityPersister
And this is only the first error shown in the console.
Well, I am trying to understand the first part of the whole line, which is
Unsatisfied dependency expressed through field customerDAO Unsatisfied dependency expressed through field customerDAO. It is giving a 500 server error. I cannot find any similar solution, neither see where the error is. Here are my source code files so far:
the entity class
package com.wcorp.springdemo.entity;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
#Entity
#Table(name="customer")
public class Customer {
#Id
#GeneratedValue(strategy=GenerationType.IDENTITY)
#Column(name="id")
private int id;
#Column(name="first_name")
private String firstName;
#Column(name="last_name")
private String lastName;
#Column(name="email")
private String email;
public Customer() {
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
#Override
public String toString() {
return "Customer [id=" + id + ", firstName=" + firstName + ", lastName=" + lastName + ", email=" + email + "]";
}
}
the dao Interface and its implementation
import com.wcorp.springdemo.entity.Customer;
public interface CustomerDAO {
public List<Customer> getCustomers();
}
import javax.transaction.Transactional;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.query.Query;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import com.wcorp.springdemo.entity.Customer;
#Repository
public class CustomerDAOImpl implements CustomerDAO {
// need to inject the session factory
#Autowired
private SessionFactory sessionFactory;
#Override
#Transactional
public List<Customer> getCustomers() {
// get the current hibernate session
Session currentSession = sessionFactory.getCurrentSession();
// create a query
Query<Customer> theQuery =
currentSession.createQuery("from Customer", Customer.class);
// execute query and get result list
List<Customer> customers = theQuery.getResultList();
// return the results
return customers;
}
}
The controller
package com.wcorp.springdemo.controller;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import com.wcorp.springdemo.dao.CustomerDAO;
import com.wcorp.springdemo.entity.Customer;
#Controller
#RequestMapping("/customer")
public class CustomerController {
// need to inject the customer dao
#Autowired
private CustomerDAO customerDAO;
#RequestMapping("/list")
public String listCustomers(Model theModel) {
// get customers from the dao
List<Customer> theCustomers = customerDAO.getCustomers();
// add the customers to the model
theModel.addAttribute("customers", theCustomers);
return "list-customers";
}
}
Here is the spring config 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: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.wcorp.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" />
<property name="user" value="springstudent2" />
<property name="password" value="springstudent2" />
<!-- these are connection pool properties for C3P0 -->
<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.wcorp.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" />
</beans>
the project build path, jars and tomcat server is fine eclipse is not complaining, spring version is 5.0.2, hibernate version 5.2.17
I found a similar problem described here
Please try to run under Java 8. The problem comes that you use Java 11.
Most of the frameworks are not compatible and are not fully tested on Java 11.

How to catch Spring bean creation error - Injection of autowired dependency?

AdminService.java
package service;
import java.util.HashMap;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import dao.IAdminDAO;
import dao.IMemberDAO;
public interface AdminService
{
public HashMap<String, Object> adminLogin(String id,String pw);
}
AdminServiceImple.java
package service;
import java.util.HashMap;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import dao.IAdminDAO;
#Service
public class AdminServiceImple implements AdminService
{
#Autowired
private IAdminDAO adminDao;
#Override
public HashMap<String, Object> adminLogin(String id, String pw)
{
HashMap<String, Object> adminResult = adminDao.selectOne(id);
if(adminResult != null)
{
String opwd = (String) adminResult.get("pw");
if(opwd.equals(pw))
{
if(adminResult.get("authority").equals(true))
{
return adminResult;
}
else
{
return null;
}
}
else
{
return null;
}
}
else
{
return null;
}
}
}
AdminController.java
package controller;
import java.io.IOException;
import java.util.HashMap;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;
import service.AdminService;
import service.AdminServiceImple;
import service.MemberService;
#Controller
public class AdminController
{
#Autowired
public AdminServiceImple adminService;
// 관리자 로그인 폼 페이지
#RequestMapping("admin.do")
public String adminLoginPage()
{
return "adminLoginPage";
}
// 관리자 로그인했을 시 요청
#RequestMapping("adminLoginOK.do")
#ResponseBody
public String adminMainPage(#RequestParam(required=false) String id, #RequestParam(required=false)String pw,HttpSession session,HttpServletRequest req,HttpServletResponse resp)
{
HashMap<String, Object> adminLoginIdentify = adminService.adminLogin(id, pw);
if(adminLoginIdentify != null)
{
return "1";
}
else
{
return "0";
}
}
#RequestMapping("adminPage.do")
public String adminPage(HttpSession session,HttpServletRequest resquest,HttpServletResponse response) throws IOException
{
return "adminMainPage";
}
}
applicationContext.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:mybatis-spring="http://mybatis.org/schema/mybatis-spring"
xsi:schemaLocation="http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-4.3.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.3.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-4.1.xsd">
<context:component-scan base-package="dao, service" />
<bean class="org.springframework.jdbc.datasource.DriverManagerDataSource" id="dataSource">
<property value="com.mysql.jdbc.Driver" name="driverClassName"></property>
<property value="jdbc:mysql://localhost/rachelvf" name="url"></property>
<property value="root" name="username"/>
<property value="mysql" name="password"/>
</bean>
<bean class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="mapperLocations" value="classpath:dao/mapper/*.xml"></property>
<property name="typeAliasesPackage" value="model"></property>
<property name="dataSource" ref="dataSource"></property>
</bean>
<bean class="org.mybatis.spring.mapper.MapperFactoryBean" id="memberDao">
<property name="mapperInterface" value="dao.IMemberDAO"></property>
<property name="sqlSessionFactory" ref="SqlSessionFactory"></property>
</bean>
<bean class="org.mybatis.spring.mapper.MapperFactoryBean" id="adminDao">
<property name="mapperInterface" value="dao.IAdminDAO"></property>
<property name="sqlSessionFactory" ref="SqlSessionFactory"></property>
</bean>
</beans>
that is error code.
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'adminServiceImple': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private dao.IAdminDAO service.AdminServiceImple.adminDao; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [dao.IAdminDAO] 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)}
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:334)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1210)
I thought about the cause of the error, but I think it is because I did not insert the service annotation.
However, there is no typos in any way, and everything is written correctly and errors occur. Is there something I don't know?
Can you tell me what caused this error?
And what about the solution?
make sure that AdminDao bean is creating and injecting correctly into
AdminServiceImple
use this tag in your spring-cfg.xml file
<context:component-scan base-package="dao" />
and also scan the controller class using --
<context:component-scan base-package="controller" />
you have to give information of class which are going to use annotation to IOC container to create bean...
A mapper is registered to Spring by including a MapperFactoryBean in your XML config file like follows:
<bean id="userMapper" class="org.mybatis.spring.mapper.MapperFactoryBean">
<property name="mapperInterface" value="org.mybatis.spring.sample.mapper.UserMapper" />
<property name="sqlSessionFactory" ref="sqlSessionFactory" />
</bean>
try this to scan your Service Package and Dao Package.
<context:component-scan base-package="dao, service" />
above code will scan the dao and service package respectively.

Having issues autowiring a sessionfactory bean with spring mvc and hibernate

I am trying to implement auto-wiring into my project, but it seems that my application isn't seeing my SessionFactory definition in my application-context.xml when I am running it.
I'm probably missing something really obvious, though I've tried several solutions from posts having similar issues with no success.
I am using Spring MVC and Hibernate.
Here is my application-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: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-3.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-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-2.5.xsd">
<context:annotation-config />
<context:component-scan base-package="arlua" />
<bean
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix">
<value>/pages/</value>
</property>
<property name="suffix">
<value>.jsp</value>
</property>
</bean>
<bean id="serverDatasource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName">
<value>oracle.jdbc.driver.OracleDriver</value>
</property>
<property name="url">
<value>url</value>
</property>
<property name="username">
<value>${user}</value>
</property>
<property name="password">
<value>${pwd}</value>
</property>
</bean>
<bean id="propertyPlaceholderConfigurer"
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="systemPropertiesModeName" value="SYSTEM_PROPERTIES_MODE_OVERRIDE" />
<property name="ignoreUnresolvablePlaceholders" value="true"/>
</bean>
<bean id="mySessionFactory"
class="org.springframework.orm.hibernate3.annotation.LocalSessionFactoryBean">
<property name="mappingResources">
<list>
<value>mapping/user_info.hbm.xml</value>
<value>mapping/login.hbm.xml</value>
<value>mapping/linked_accounts.hbm.xml</value>
<value>mapping/application_instance.hbm.xml</value>
</list>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
<prop key="hibernate.hbm2ddl.auto">update</prop>
</props>
</property>
<property name="dataSource" ref="serverDatasource"/>
</bean>
<bean id = "userInfoDaoImpl" class="arlua.dao.impl.UserInfoDaoImpl">
<property name="sessionFactory" ref="mySessionFactory"/>
</bean>
<bean id = "loginDaoImpl" class="arlua.dao.impl.LoginDaoImpl">
<property name="sessionFactory" ref="mySessionFactory"/>
</bean>
<bean id = "linkedAccountsDaoImpl" class="arlua.dao.impl.LinkedAccountsDaoImpl">
<property name="sessionFactory" ref="mySessionFactory"/>
</bean>
<!--
<bean id = "applicationInstanceDaoImpl" class="arlua.dao.impl.ApplicationInstanceDaoImpl">
<property name="sessionFactory" ref="mySessionFactory"/>
</bean>
-->
<!-- ************* TRANSACTION MANAGEMENT USING AOP **************** -->
<bean id="myTransactionManager"
class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="mySessionFactory"/>
</bean>
<aop:config>
<aop:pointcut id="allMethods" expression="execution(* arlua.dao.TableEntityFetchDao.*(..))"/>
<aop:advisor advice-ref="txAdvice" pointcut-ref="allMethods"/>
</aop:config>
<tx:advice id="txAdvice" transaction-manager="myTransactionManager">
<tx:attributes>
<tx:method name="saveEntity"
propagation = "REQUIRES_NEW"
isolation = "READ_COMMITTED"
rollback-for = "Exception"/>
<tx:method name="updateEntity"
propagation = "REQUIRES_NEW"
isolation = "READ_COMMITTED"
rollback-for = "Exception"/>
<tx:method name="getEntity"
propagation = "REQUIRES_NEW"
isolation = "READ_COMMITTED"
rollback-for = "Exception"/>
<tx:method name="getAllEntities"
propagation = "REQUIRES_NEW"
isolation = "READ_COMMITTED"
rollback-for = "Exception"/>
</tx:attributes>
</tx:advice>
</beans>
Here is the controller class where I am trying to autowire.
package arlua.controller;
import arlua.dao.TableEntityFetchDao;
import arlua.dao.impl.ApplicationInstanceDaoImpl;
import arlua.service.SearchCriteria;
import arlua.service.UserAction;
import arlua.tables.ApplicationInstanceTable;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
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.bind.annotation.SessionAttributes;
import org.springframework.web.servlet.ModelAndView;
#Controller
#SessionAttributes
public class SearchAppController{
#Autowired public ApplicationInstanceDaoImpl applicationInstanceDaoImpl;
private String input;
private ApplicationInstanceTable oldApp, newApp;
#RequestMapping(value = "/search_app_instance", method = RequestMethod.POST)
public String mySearchMethod(#ModelAttribute("search_criteria") SearchCriteria search){
input = search.getInput();
if(input != null)
input = input.toUpperCase();
return "redirect:search_app_instance";
}
#RequestMapping("/search_app_instance")
public ModelAndView mySuccessMethod(){
ModelAndView model = new ModelAndView("search_app_instance");
//Check and Make sure that the app exists
//ApplicationContext factory =
// new ClassPathXmlApplicationContext("spring-namespace.xml");
//TableEntityFetchDao urd = (TableEntityFetchDao)factory.getBean("applicationInstanceDaoImpl");
try{
ApplicationInstanceTable app =
(ApplicationInstanceTable) applicationInstanceDaoImpl.getEntity(input);
oldApp = app;
//Load app data into table
model.addObject("app_id", app.getApplication_id());
model.addObject("name", app.getName());
model.addObject("default_exp_period", app.getDefault_expiration_period());
model.addObject("server", app.getServer());
model.addObject("description", app.getDescription());
model.addObject("active", app.getActive());
model.addObject("conn_string", app.getConn_string());
model.addObject("creation_date", app.getCreation_date().getTime());
model.addObject("error", "");
}
catch(Exception e){
if(input != null)
{
model.addObject("error", "Application could not be found.");
input = "";
}
}
return model;
}
#RequestMapping(value = "/app_actions", method = RequestMethod.POST)
public String userActionsMethod(#ModelAttribute("user_action") UserAction action,
#ModelAttribute("app_info") ApplicationInstanceTable app_info){
if(action.getAction().equals("update_info"))
{
newApp = app_info;
return "redirect:update_app_info";
}
return "redirect:search_app_instance";
}
#RequestMapping("/update_app_info")
public ModelAndView updateInfoMethod(){
ModelAndView model = new ModelAndView("search_app_instance");
ApplicationContext factory =
new ClassPathXmlApplicationContext("spring-namespace.xml");
TableEntityFetchDao urd = (TableEntityFetchDao)factory.getBean("applicationInstanceDaoImpl");
newApp.setApplication_id(oldApp.getApplication_id());
newApp.setCreation_date(oldApp.getCreation_date());
urd.updateEntity(newApp);
model.addObject("msg", "Application '" + newApp.getApplication_id() + "' modified successfully.");
return model;
}
}
ApplicationInstanceDaoImpl Class
package arlua.dao.impl;
import arlua.dao.TableEntityFetchDao;
import arlua.tables.ApplicationInstanceTable;
import java.util.List;
import javax.annotation.Resource;
import org.hibernate.SessionFactory;
import org.springframework.stereotype.Repository;
#Repository("applicationInstanceDaoImpl")
public class ApplicationInstanceDaoImpl extends TableEntityFetchDao{
public SessionFactory mySessionFactory;
#Resource(name = "mySessionFactory")
public void setMySessionFactory(SessionFactory mySessionFactory){
this.mySessionFactory = mySessionFactory;
}
public void saveEntity(Object applicationInstance) {
this.mySessionFactory.getCurrentSession().save((ApplicationInstanceTable)applicationInstance);
}
public ApplicationInstanceTable getEntity(Object application_id) {
return (ApplicationInstanceTable)this.mySessionFactory.getCurrentSession().
get(ApplicationInstanceTable.class, (String)application_id);
}
public void updateEntity(Object applicationInstance) {
this.mySessionFactory.getCurrentSession().update((ApplicationInstanceTable)applicationInstance);
}
public void deleteEntity(Object applicationInstance) {
this.mySessionFactory.getCurrentSession().delete((ApplicationInstanceTable)applicationInstance);
}
public List<?> getAllEntities() {
return this.mySessionFactory.getCurrentSession().createQuery
("FROM application_instance").list();
}
}
TableEntityFetchDao class
package arlua.dao;
import java.util.List;
import org.hibernate.SessionFactory;
/*
This class will serve as a generic blueprint for all of the other data access implementation classes
that are used to perform basic CRUD operations on the arlua tables (ie UserInfoDaoImpl).
*/
public abstract class TableEntityFetchDao {
private SessionFactory sessionFactory;
public void setSessionFactory(SessionFactory sessionFactory){
this.sessionFactory = sessionFactory;
}
public abstract void saveEntity(final Object entity);
public abstract Object getEntity(final Object key);
public abstract void updateEntity(final Object entity);
public abstract void deleteEntity(final Object entity);
public abstract List<?> getAllEntities();
}
Here is most of my stack trace.
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping#0': Initialization of bean failed; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'searchAppController': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: public arlua.dao.impl.ApplicationInstanceDaoImpl arlua.controller.SearchAppController.applicationInstanceDaoImpl; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'applicationInstanceDaoImpl': Injection of resource dependencies failed; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'mySessionFactory' is defined
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:527)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:456)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:291)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:288)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:190)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:580)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:895)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:425)
at org.springframework.web.context.ContextLoader.createWebApplicationContext(ContextLoader.java:276)
at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:197)
at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:47)
at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:4206)
at org.apache.catalina.core.StandardContext.start(StandardContext.java:4705)
at org.apache.catalina.core.ContainerBase.start(ContainerBase.java:1057)
at org.apache.catalina.core.StandardHost.start(StandardHost.java:840)
at org.apache.catalina.core.ContainerBase.start(ContainerBase.java:1057)
at org.apache.catalina.core.StandardEngine.start(StandardEngine.java:463)
at org.apache.catalina.core.StandardService.start(StandardService.java:525)
at org.apache.catalina.core.StandardServer.start(StandardServer.java:754)
at org.apache.catalina.startup.Catalina.start(Catalina.java:595)
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.apache.catalina.startup.Bootstrap.start(Bootstrap.java:289)
at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:414)
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'searchAppController': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: public arlua.dao.impl.ApplicationInstanceDaoImpl arlua.controller.SearchAppController.applicationInstanceDaoImpl; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'applicationInstanceDaoImpl': Injection of resource dependencies failed; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'mySessionFactory' is defined
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:285)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1074)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:517)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:456)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:291)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:288)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:190)
at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1075)
at org.springframework.web.servlet.handler.AbstractUrlHandlerMapping.registerHandler(AbstractUrlHandlerMapping.java:383)
at org.springframework.web.servlet.handler.AbstractUrlHandlerMapping.registerHandler(AbstractUrlHandlerMapping.java:362)
at org.springframework.web.servlet.handler.AbstractDetectingUrlHandlerMapping.detectHandlers(AbstractDetectingUrlHandlerMapping.java:82)
at org.springframework.web.servlet.handler.AbstractDetectingUrlHandlerMapping.initApplicationContext(AbstractDetectingUrlHandlerMapping.java:58)
at org.springframework.context.support.ApplicationObjectSupport.initApplicationContext(ApplicationObjectSupport.java:119)
at org.springframework.web.context.support.WebApplicationObjectSupport.initApplicationContext(WebApplicationObjectSupport.java:72)
at org.springframework.context.support.ApplicationObjectSupport.setApplicationContext(ApplicationObjectSupport.java:73)
at org.springframework.context.support.ApplicationContextAwareProcessor.invokeAwareInterfaces(ApplicationContextAwareProcessor.java:106)
at org.springframework.context.support.ApplicationContextAwareProcessor.postProcessBeforeInitialization(ApplicationContextAwareProcessor.java:85)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyBeanPostProcessorsBeforeInitialization(AbstractAutowireCapableBeanFactory.java:394)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1413)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:519)
... 26 more
Caused by: org.springframework.beans.factory.BeanCreationException: Could not autowire field: public arlua.dao.impl.ApplicationInstanceDaoImpl arlua.controller.SearchAppController.applicationInstanceDaoImpl; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'applicationInstanceDaoImpl': Injection of resource dependencies failed; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'mySessionFactory' is defined
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:502)
at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:84)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:282)
... 46 more
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'applicationInstanceDaoImpl': Injection of resource dependencies failed; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'mySessionFactory' is defined
at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor.postProcessPropertyValues(CommonAnnotationBeanPostProcessor.java:300)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1074)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:517)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:456)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:291)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:288)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:190)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.findAutowireCandidates(DefaultListableBeanFactory.java:844)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:786)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:703)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:474)
... 48 more
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'mySessionFactory' is defined
at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBeanDefinition(DefaultListableBeanFactory.java:527)
at org.springframework.beans.factory.support.AbstractBeanFactory.getMergedLocalBeanDefinition(AbstractBeanFactory.java:1083)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:274)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:194)
at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor.autowireResource(CommonAnnotationBeanPostProcessor.java:435)
at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor.getResource(CommonAnnotationBeanPostProcessor.java:409)
at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor$ResourceElement.getResourceToInject(CommonAnnotationBeanPostProcessor.java:541)
at org.springframework.beans.factory.annotation.InjectionMetadata$InjectedElement.inject(InjectionMetadata.java:156)
at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:84)
at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor.postProcessPropertyValues(CommonAnnotationBeanPostProcessor.java:297)
... 59 more
Edit: I ended up fixing my problem by autowiring into the interface TableEntityFetchDao rather than the class that was implementing it, ApplicationInstanceDaoImpl.
So, this
#Autowired public ApplicationInstanceDaoImpl applicationInstanceDaoImpl;
Became this
#Autowired public TableEntityFetchDao applicationInstanceDao;
And that seemed to fix my problem.
Instead of:
#Resource(name = "mySessionFactory")
public void setMySessionFactory(SessionFactory mySessionFactory){
this.mySessionFactory = mySessionFactory;
}
Use:
#Autowired
private SessionFactory mySessionFactory;
EDIT
As of the bellow comment:
Not sure why method is not working but my guess is that the parent TableEntityFetchDao class has the setter of session factory, then ApplicationInstanceDaoImpl - child class overrides it and spring for some reason does not like it, if TableEntityFetchDao would be an interface, setter would be injected, as #Resource serves the same purpose as #Autowired difference is that #Resource allows to specify the name of the bean which is injected, and #Autowire allows you mark the bean as not required.
To get #Resource working I would try to remove setter method from the parent class. Either way it makes no sense of having it there as it is not used. Also sessionFactory field. This can be removed as well. Then class contains only abstract methods and can be made an interface. Also I would annotate TableEntityFetchDao with #Service annotation for better understanding that it is a service-layer class.
#Resource(name = "mySessionFactory")
public void setMySessionFactory(SessionFactory mySessionFactory){
this.mySessionFactory = mySessionFactory;
}
try as #Autowired
public void setMySessionFactory(SessionFactory mySessionFactory){
this.mySessionFactory = mySessionFactory;
}
modify your code from the below code snippet in your spring configuration file
<bean id="mySessionFactory"
class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="mappingLocations">
<list>
<value>mapping/user_info.hbm.xml</value>
<value>mapping/login.hbm.xml</value>
<value>mapping/linked_accounts.hbm.xml</value>
<value>mapping/application_instance.hbm.xml</value>
</list>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
<prop key="hibernate.hbm2ddl.auto">update</prop>
</props>
</property>
<property name="dataSource" ref="serverDatasource"/>
I hope this code will work for you, and let me know , if still you are facing the problem

java.lang.IllegalArgumentException: 'sessionFactory' or 'hibernateTemplate' is required in spring+hibernate

I am doing spring + hibernate apllication. When I run the application on tomcat server I am getting some exception. Below is my code.
This is my bean config 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"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">
<bean
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="location">
<value>WEB-INF/database/db.properties</value>
</property>
</bean>
<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.hibernate3.LocalSessionFactoryBean">
<property name="dataSource">
<ref bean="dataSource" />
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.show_sql">true</prop>
</props>
</property>
<property name="mappingResources">
<list>
<value>Employee.hbm.xml</value>
</list>
</property>
</bean>
<bean id="employeeBo" class="com.saggezza.employee.bo.impl.EmployeeBoImpl">
<property name="employeeDao" ref="employeeDao" />
</bean>
<bean id="employeeDao" class="com.saggezza.employee.dao.impl.EmployeeDaoImpl">
<constructor-arg ref="sessionFactory"></constructor-arg>
</bean>
this is my dao class.
public class EmployeeDaoImpl extends HibernateDaoSupport implements EmployeeDao {
private SessionFactory sessionFactory;
public EmployeeDaoImpl(SessionFactory sessionfactory){
this.sessionFactory=sessionfactory;
}
#Override
public List<Employee> getEmployeeDetails() {
return getHibernateTemplate().find("from Employee");
}
}
Here another class employeeBo is calling the employeeDaoImpl.
when I run thisI am getting the below exception.
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'employeeBo' defined in ServletContext resource [/WEB-INF/spring/EmployeeBean.xml]: Cannot resolve reference to bean 'employeeDao' while setting bean property 'employeeDao'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'employeeDao' defined in ServletContext resource [/WEB-INF/spring/EmployeeBean.xml]: Invocation of init method failed; nested exception is java.lang.IllegalArgumentException: 'sessionFactory' or 'hibernateTemplate' is required
Can anybody help to resolve this. I have tried a lot and google it as well.But did get the solution.
If you have two configuration files, you duplicates 'sessionFactory' definition. Remove one of the 'sessionFactory' definitions . You would have got duplicate bean definition exception before the IllegalArgumentException.
Edit: After your comment,
public class EmployeeDaoImpl extends HibernateDaoSupport implements EmployeeDao {
public EmployeeDaoImpl(SessionFactory sessionfactory){
setSessionFactory(sessionfactory);
}
#Override
public List<Employee> getEmployeeDetails() {
return getHibernateTemplate().find("from Employee");
}
}
or get rid of constructor in above code and inject 'sessionFactory' using setter injection.See org.springframework.orm.hibernate3.support.HibernateDaoSupport.setSessionFactory(SessionFactory). I prefer later approach.
I think the problem is the type of SessionFactory you are injecting in EmployeeDaoImpl does not match with the type of the SessionFactory you used in the class.
Can you check it?
This is an old question so must be solved now but still if someone comes across this problem. Following is solution.
You can use Hibernate DAO Support by extending HibernateDAOSupport class and overriding its afterPropertiesSet() method.
This method is called in HibernateDAO support and at that time since sessionFactory is null it is throwing this error. In your custom class you can set this property explicitly and then call the same method of Parent Class (i.e. HibernateDAOSupport's addProperties() method)
package com.techcielo.spring4.hibernate.template;
import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.orm.hibernate3.HibernateTemplate;
import org.springframework.stereotype.Component;
#Component("hibernateTemplate")
public class Hibernate4CustomTemplate extends HibernateTemplate{
#Autowired(required=true)
private SessionFactory sessionFactory;
public void setSessionFactory(SessionFactory sessionFactory) {
System.out.println("Setting SessionFactory");
this.sessionFactory = sessionFactory;
super.setSessionFactory(sessionFactory);
}
#Override
public void afterPropertiesSet() {
System.out.println("Checking if properties set..."+this.sessionFactory);
setSessionFactory(sessionFactory);
super.afterPropertiesSet();
}
}
Following can be used for sample!
I had the same problem and fix it by using Autowired constructor with EntityManagerFactory. Keyur answer is correct
#Service
class EmployeeDaoImpl #Autowired constructor(
factory: EntityManagerFactory
) : HibernateDaoSupport(), EmployeeDao {
init {
if (factory.unwrap(SessionFactory::class.java) == null) {
throw NullPointerException("factory is not a hibernate factory")
}
setSessionFactory(factory.unwrap(SessionFactory::class.java))
}
...
}

Autowired Fails with Spring Junit Test

Writing Junit Tests for my spring application. Because I am new at this I tried starting off by writing a Unit Test for a DAO class that I know works (ran it in JBoss). However, I cannot get it to work as a Unit Test in Eclipse. I keep getting an "Error creating bean... Could not autowire field: NoSuchBeanDefinition".
I saw errors similar to this on StackOverflow and other sites and it always ended up being a syntax error or attempting to autowire the Implementation of the interface as opposed to the Interface, etc. I don't see any of those errors with my code.
I did download Spring-test.jar separately from the Spring configuration that came with the project. Both are from Spring 2.5 however, so I don't think that should be an issue :/
Eclipse comes bundled with JUnit 4.8 and Spring Unit Test doesn't work with that so I downgraded my JUnit to use 4.4
One thing to consider... if you look at the code for my Unit Test you will notice that I autowire two fields: a SimpleJdbcTemplate at the Query Service I want to test. Well if I remove the DrugDao and all references to it, then the SimpleJdbcQuery auto-wires just fine.
Here is the stacktrace for your review:
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'tst.hcps.glucosemanagement.dataaccess.DrugDaoTest': Autowiring of fields failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: com.hcps.glucosemanagement.repository.meds.DrugDao tst.hcps.glucosemanagement.dataaccess.DrugDaoTest.dQuery; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No unique bean of type [com.hcps.glucosemanagement.repository.meds.DrugDao] is defined: Unsatisfied dependency of type [interface com.hcps.glucosemanagement.repository.meds.DrugDao]: expected at least 1 matching bean
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessAfterInstantiation(AutowiredAnnotationBeanPostProcessor.java:243)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:959)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireBeanProperties(AbstractAutowireCapableBeanFactory.java:329)
at org.springframework.test.context.support.DependencyInjectionTestExecutionListener.injectDependencies(DependencyInjectionTestExecutionListener.java:127)
at org.springframework.test.context.support.DependencyInjectionTestExecutionListener.prepareTestInstance(DependencyInjectionTestExecutionListener.java:85)
at org.springframework.test.context.TestContextManager.prepareTestInstance(TestContextManager.java:231)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.createTest(SpringJUnit4ClassRunner.java:95)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.invokeTestMethod(SpringJUnit4ClassRunner.java:139)
at org.junit.internal.runners.JUnit4ClassRunner.runMethods(JUnit4ClassRunner.java:51)
at org.junit.internal.runners.JUnit4ClassRunner$1.run(JUnit4ClassRunner.java:44)
at org.junit.internal.runners.ClassRoadie.runUnprotected(ClassRoadie.java:27)
at org.junit.internal.runners.ClassRoadie.runProtected(ClassRoadie.java:37)
at org.junit.internal.runners.JUnit4ClassRunner.run(JUnit4ClassRunner.java:42)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:49)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)
Caused by: org.springframework.beans.factory.BeanCreationException: Could not autowire field: com.hcps.glucosemanagement.repository.meds.DrugDao tst.hcps.glucosemanagement.dataaccess.DrugDaoTest.dQuery; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No unique bean of type [com.hcps.glucosemanagement.repository.meds.DrugDao] is defined: Unsatisfied dependency of type [interface com.hcps.glucosemanagement.repository.meds.DrugDao]: expected at least 1 matching bean
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:435)
at org.springframework.beans.factory.annotation.InjectionMetadata.injectFields(InjectionMetadata.java:105)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessAfterInstantiation(AutowiredAnnotationBeanPostProcessor.java:240)
... 18 more
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No unique bean of type [com.hcps.glucosemanagement.repository.meds.DrugDao] is defined: Unsatisfied dependency of type [interface com.hcps.glucosemanagement.repository.meds.DrugDao]: expected at least 1 matching bean
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:613)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:412)
... 20 more
Here is the Interface and Implementation:
DrugDao.java
package com.hcps.glucosemanagement.repository.meds;
import java.util.List;
import com.hcps.glucosemanagement.domain.meds.Drug;
public interface DrugDao {
public List<Drug> searchDrugsByPrimaryName(String facilityId, String name);
public List<Drug> searchDrugs(String facilityId, String primaryName, String secondaryName);
}
SpringJdbcDrugQuery.java
package com.hcps.glucosemanagement.repository.meds;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.List;
import org.apache.log4j.Logger;
import org.springframework.dao.EmptyResultDataAccessException;
import org.springframework.jdbc.core.simple.ParameterizedRowMapper;
import org.springframework.stereotype.Service;
import com.hcps.glucosemanagement.domain.meds.Drug;
import com.hcps.glucosemanagement.repository.DaoOperations;
#Service
public class SpringJdbcDrugQuery extends DaoOperations implements DrugDao {
private static final Logger logger = Logger.getLogger(SpringJdbcDrugQuery.class);
public List<Drug> searchDrugsByPrimaryName(String facilityId, String name)
{
return searchDrugs(facilityId, name, null);
}
public List<Drug> searchDrugs(String facilityId, String primaryName, String secondaryName)
{
List<Drug> results = null;
StringBuffer sql = new StringBuffer();
HashMap<String, Object> namedParameters = new HashMap<String, Object>();
if(primaryName==null) return null;
sql = new StringBuffer();
sql.append("SELECT");
...
results = simpleJdbcTemplate.query(sql.toString(), new DrugMapper(),
return results;
}
private static final class DrugMapper implements ParameterizedRowMapper<Drug>
{
public Drug mapRow(ResultSet rs, int rowNum) throws SQLException {
Drug drug = new Drug();
drug.setFacilityId(rs.getString("FACILITY_ID"));
drug.setPrimaryName(rs.getString("PRIMARY_NAME"));
drug.setSecondaryName(rs.getString("SEC_NAME"));
return drug;
}
}
}
DrugDaoTest2.java (located in a separate source folder at first, then tried it in the same folder)
package com.hcps.glucosemanagement.repository.meds;
import static org.junit.Assert.assertTrue;
import java.util.List;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.simple.SimpleJdbcTemplate;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import com.hcps.glucosemanagement.domain.meds.Drug;
#RunWith(SpringJUnit4ClassRunner.class)
#ContextConfiguration(locations={
"classpath:common-test.xml"
})
public class DrugDaoTest2 {
#Autowired
DrugDao dQuery;
#Autowired
SimpleJdbcTemplate queryTemplate;
#Test public void glucoseFetch() {
List<Drug> rslts = dQuery.searchDrugsByPrimaryName(null, "INSU*");
assertTrue(rslts.size()>0);
int i=0;
System.out.println(i);
}
public void setDrugDao(DrugDao drugDao) {
this.dQuery = drugDao;
}
}
common-test.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"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd"
>
<!--
Test configuration for Spring/JUnit Testing
-->
<bean id="contextApplicationContextProvider" class="com.hcps.glucosemanagement.spring.ApplicationContextProvider" />
<bean id="jmxExporter" class="org.springframework.jmx.export.MBeanExporter" lazy-init="false">
<property name="beans">
<map>
<entry key="bean:name=Log4jJmxServiceMBean" value-ref="glucosemanagement.Log4jJmxService" />
</map>
</property>
</bean>
<bean id="glucosemanagement.Log4jJmxService" class="com.hcps.glucosemanagement.logging.Log4jJmxService" />
<bean id="messageSource" class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
<property name="basename" value="/WEB-INF/messages" />
</bean>
<bean id="parameterMappingInterceptor" class="org.springframework.web.portlet.handler.ParameterMappingInterceptor" />
<bean id="viewResolverCommon" class="org.springframework.web.servlet.view.InternalResourceViewResolver"
p:order="2"
p:cache="false"
p:viewClass="org.springframework.web.servlet.view.JstlView"
p:prefix="/WEB-INF/jsp/"
p:suffix=".jsp"
/>
<bean id="defaultExceptionHandler" class="org.springframework.web.portlet.handler.SimpleMappingExceptionResolver">
<property name="defaultErrorView" value="../error"/>
<property name="exceptionMappings">
<props>
<prop key="javax.portlet.PortletSecurityException">notAuthorized</prop>
<prop key="javax.portlet.UnavailableException">notAvailable</prop>
</props>
</property>
</bean>
<bean id="simpleParameterJdbcTemplate" class="org.springframework.jdbc.core.simple.SimpleJdbcTemplate">
<constructor-arg ref="hciDataSource" />
</bean>
<bean id="hciDataSource" class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName" value="oracle.jdbc.driver.OracleDriver" />
<property name="url" value="jdbc:oracle:thin:#//vir-tst.com:1521/qar01.world" />
<property name="username" value="ccuser" />
<property name="password" value="bueno" />
<property name="maxActive" value="30" />
<property name="maxWait" value="30" />
<property name="maxIdle" value="30" />
</bean>
</beans>
My mistake: there was another Spring Configuration file referenced elsewhere that I missed. Adding this field and defining setters in my Unit Test for any autowired fields solved the problem.
I am using this checklist now when these types of errors occur:
Make sure that implementing class of Interface type uses “#Service”
annotation
Make sure beans are configured properly in the XML:
Simplest way is to use:
<context:component-scan base-package="com.customization.packagename" />
This adds all classes under the package name
Or create XML Bean Definitions
I had the similar issue and found that while I could AutoWire classes successfully in Eclipse, surefire required only interfaces to be AutoWired. Especially this occurs only when using Cobertura for instrumenting, so pretty sure there is something wrong with the proxy generation. For now, I have just introduced a new interface as it was appropriate for my use-case but there should definitely be another appropriate solution.
Add a bean definition of type SpringJdbcDrugQuery to common-test.xml
I encounter this problem too, and I just add setter, then it works well.

Resources