I am trying to set up a spring mvc application with a few students for a project at university, it's a web based cookbook.
While Hello World worked, we get some difficult exceptions for our code using hibernate to store the data.
The domain class:
/**
* POJO which represents a Recipe.
* @author Nils Sommer
*
*/
@Entity
@Table(name="recipes")
public class Recipe implements Serializable {
private static final long serialVersionUID = 3239162951065313443L; // generated by eclipse
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
private int id;
@Column(name="title")
private String title;
@Column(name="description")
private String description;
@Column(name="content")
private String content;
@Column(name="preparation_endurance")
private int preparationEndurance;
@Column(name="total_endurance")
private int totalEndurance;
@Column(name="creation")
private Date creation;
private List<Image> images;
private List<Rating> ratings;
// ----- Getters and setters here: -----
}
The Service class:
@Service("recipeService")
@Transactional
public class RecipeService {
protected static Logger logger = Logger.getLogger("service");
@Resource(name="sessionFactory")
private SessionFactory sessionFactory;
public Recipe getRecipe(int id) {
logger.debug("Retrieving person with id: " + id);
// Retrieve session from Hibernate
Session session = sessionFactory.getCurrentSession();
// Get recipe
Recipe recipe = (Recipe) session.get(Recipe.class, id);
// Retrieve recipe
return recipe;
}
public List<Recipe> getAll() {
logger.debug("Retrieving all persons");
// Retrieve session from Hibernate
Session session = sessionFactory.getCurrentSession();
// Create a Hibernate query (HQL)
Query query = session.createQuery("FROM Person");
// Retrieve all
return query.list();
}
public void add(String title, String description, String content,
int preparationEndurance, int totalEndurance, Date creation) {
logger.debug("Adding new person");
// Retrieve session from Hibernate
Session session = sessionFactory.getCurrentSession();
// Create a new Recipe
Recipe recipe = new Recipe();
recipe.setTitle(title);
recipe.setDescription(description);
recipe.setContent(content);
recipe.setPreparationEndurance(preparationEndurance);
recipe.setTotalEndurance(totalEndurance);
recipe.setCreation(creation);
// Save
session.save(recipe);
}
public void delete(Integer id) {
logger.debug("Deleting existing person");
// Retrieve session from Hibernate
Session session = sessionFactory.getCurrentSession();
// Retrieve existing recipe first
Recipe person = (Recipe) session.get(Recipe.class, id);
// Delete
session.delete(person);
}
public void edit(Integer id, String title, String description, String content,
int preparationEndurance, int totalEndurance, Date creation) {
logger.debug("Editing existing person");
// Retrieve session from Hibernate
Session session = sessionFactory.getCurrentSession();
// Retrieve existing recipe via id
Recipe recipe = (Recipe) session.get(Recipe.class, id);
// Assign updated values to this recipe
recipe.setTitle(title);
recipe.setDescription(description);
recipe.setContent(content);
recipe.setPreparationEndurance(preparationEndurance);
recipe.setTotalEndurance(totalEndurance);
recipe.setCreation(creation);
// Save updates
session.save(recipe);
}
}
The Controller class:
package org.cookbookgeeks.webkochbuch.web;
/**
* @author Nils Sommer
*
* This is the Controller which processes all recipe requests.
*/
@Controller
public class RecipeController {
private static final Logger logger = LoggerFactory.getLogger(RecipeController.class);
@Resource(name="recipeService")
private RecipeService recipeService;
/**
* Shows a recipe.
* @param id of the recipe which wil be shown.
* @return the view recipe.jsp
*/
@RequestMapping(method=RequestMethod.GET, value="/recipe/{id}")
public String showRecipe(@PathVariable("id") int id, Model model) {
logger.debug("Returning view recipe with recipe.id=" + id);
// Get recipe.
Recipe recipe = recipeService.getRecipe(id);
model.addAttribute("recipe", recipe);
return "recipe";
}
/**
* Adds a recipe and shows it afterwards.
* @param recipe which is added.
* @return the view recipe with the id of the created recipe.
*/
@RequestMapping(method=RequestMethod.POST, value="/recipe/add")
public String addRecipe(@ModelAttribute("recipe") Recipe recipe) {
//TODO: create recipe from post parameter
return "/recipe/" + recipe.getId();
}
/**
* Deletes a recipe and redirects to the start page.
* @param id of the recipe which gets deleted.
* @return the view of the start page.
*/
@RequestMapping(method=RequestMethod.GET, value="/recipe/delete/{id}")
public String deleteRecipe(@PathVariable("id") int id) {
//TODO: delete recipe.
return "/";
}
/**
* Edits a recipe and show it afterwards.
* @param recipe which gets edited.
* @return the view recipe with the id of the recipe.
*/
@RequestMapping(method=RequestMethod.POST, value="/recipe/edit")
public String editRecipe(@ModelAttribute("recipe") Recipe recipe) {
//TODO: edit recipe.
return "/recipe/" + recipe.getId();
}
}
We use the eclipse based spring tool kit sdk and get the following exceptions during startup:
HTTP Status 500 - Servlet.init() for servlet appServlet threw exception
type Exception report
message Servlet.init() for servlet appServlet threw exception
description The server encountered an internal error that prevented it from fulfilling this request.
exception
javax.servlet.ServletException: Servlet.init() for servlet appServlet threw exception
org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:502)
org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:99)
org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:953)
org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:408)
org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1023)
org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:589)
org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:312)
java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
java.lang.Thread.run(Thread.java:744)
root cause
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'recipeController': Injection of resource dependencies failed; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'recipeService' is defined
org.springframework.context.annotation.CommonAnnotationBeanPostProcessor.postProcessPropertyValues(CommonAnnotationBeanPostProcessor.java:306)
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1116)
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:519)
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:458)
org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:295)
org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:223)
org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:292)
org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:194)
org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:628)
org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:932)
org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:479)
org.springframework.web.servlet.FrameworkServlet.configureAndRefreshWebApplicationContext(FrameworkServlet.java:651)
org.springframework.web.servlet.FrameworkServlet.createWebApplicationContext(FrameworkServlet.java:599)
org.springframework.web.servlet.FrameworkServlet.createWebApplicationContext(FrameworkServlet.java:665)
org.springframework.web.servlet.FrameworkServlet.initWebApplicationContext(FrameworkServlet.java:518)
org.springframework.web.servlet.FrameworkServlet.initServletBean(FrameworkServlet.java:459)
org.springframework.web.servlet.HttpServletBean.init(HttpServletBean.java:136)
javax.servlet.GenericServlet.init(GenericServlet.java:160)
org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:502)
org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:99)
org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:953)
org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:408)
org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1023)
org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:589)
org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:312)
java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
java.lang.Thread.run(Thread.java:744)
root cause
org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'recipeService' is defined
org.springframework.beans.factory.support.DefaultListableBeanFactory.getBeanDefinition(DefaultListableBeanFactory.java:570)
org.springframework.beans.factory.support.AbstractBeanFactory.getMergedLocalBeanDefinition(AbstractBeanFactory.java:1108)
org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:278)
org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:198)
org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:270)
org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:198)
org.springframework.context.annotation.CommonAnnotationBeanPostProcessor.autowireResource(CommonAnnotationBeanPostProcessor.java:442)
org.springframework.context.annotation.CommonAnnotationBeanPostProcessor.getResource(CommonAnnotationBeanPostProcessor.java:416)
org.springframework.context.annotation.CommonAnnotationBeanPostProcessor$ResourceElement.getResourceToInject(CommonAnnotationBeanPostProcessor.java:550)
org.springframework.beans.factory.annotation.InjectionMetadata$InjectedElement.inject(InjectionMetadata.java:150)
org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:87)
org.springframework.context.annotation.CommonAnnotationBeanPostProcessor.postProcessPropertyValues(CommonAnnotationBeanPostProcessor.java:303)
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1116)
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:519)
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:458)
org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:295)
org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:223)
org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:292)
org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:194)
org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:628)
org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:932)
org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:479)
org.springframework.web.servlet.FrameworkServlet.configureAndRefreshWebApplicationContext(FrameworkServlet.java:651)
org.springframework.web.servlet.FrameworkServlet.createWebApplicationContext(FrameworkServlet.java:599)
org.springframework.web.servlet.FrameworkServlet.createWebApplicationContext(FrameworkServlet.java:665)
org.springframework.web.servlet.FrameworkServlet.initWebApplicationContext(FrameworkServlet.java:518)
org.springframework.web.servlet.FrameworkServlet.initServletBean(FrameworkServlet.java:459)
org.springframework.web.servlet.HttpServletBean.init(HttpServletBean.java:136)
javax.servlet.GenericServlet.init(GenericServlet.java:160)
org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:502)
org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:99)
org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:953)
org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:408)
org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1023)
org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:589)
org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:312)
java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
java.lang.Thread.run(Thread.java:744)
note The full stack trace of the root cause is available in the VMware vFabric tc Runtime 2.9.3.RELEASE/7.0.42.A.RELEASE logs.
VMware vFabric tc Runtime 2.9.3.RELEASE/7.0.42.A.RELEASE
Seems like there is a problem with the recipeService in the Controller class ...
EDIT: 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">
<!-- The definition of the Root Spring Container shared by all Servlets and Filters -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring/root-context.xml</param-value>
</context-param>
<!-- Creates the Spring Container shared by all Servlets and Filters -->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!-- Processes application requests -->
<servlet>
<servlet-name>appServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring/appServlet/servlet-context.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>appServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>
src/main/resources/META-INF/app-context.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
xmlns:tx="http://www.springframework.org/schema/tx" xmlns:jdbc="http://www.springframework.org/schema/jdbc"
xsi:schemaLocation="
http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-3.0.xsd
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/context http://www.springframework.org/schema/context/spring-context-3.0.xsd">
<context:component-scan base-package="org.cookbookgeeks.webkochbuch" />
</beans>
src/main/webapp/WEB-INF/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: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">
<!-- Activates various annotations to be detected in bean classes -->
<context:annotation-config />
<!-- Scans the classpath for annotated components that will be auto-registered as Spring beans.
For example @Controller and @Service. Make sure to set the correct base-package-->
<context:component-scan base-package="org.cookbookgeeks.webkochbuch" />
<!-- Configures the annotation-driven Spring MVC Controller programming model.
Note that, with Spring 3.0, this tag works in Servlet MVC only! -->
<mvc:annotation-driven />
<import resource="hibernate-context.xml" />
</beans>
src/main/webapp/WEB-INF/spring/appServlet/servlet-context.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="http://www.springframework.org/schema/mvc"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:beans="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
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">
<!-- DispatcherServlet Context: defines this servlet's request-processing infrastructure -->
<!-- Enables the Spring MVC @Controller programming model -->
<annotation-driven />
<!-- Handles HTTP GET requests for /resources/** by efficiently serving up static resources in the ${webappRoot}/resources directory -->
<resources mapping="/resources/**" location="/resources/" />
<!-- Resolves views selected for rendering by @Controllers to .jsp resources in the /WEB-INF/views directory -->
<beans:bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<beans:property name="prefix" value="/WEB-INF/views/" />
<beans:property name="suffix" value=".jsp" />
</beans:bean>
<context:component-scan base-package="org.cookbookgeeks.webkochbuch.web" />
</beans:beans>
@Serviceclass getting component-scanned somehow? Post your context configuration. - chrylis -cautiouslyoptimistic-@Serviceand@Resourcenames); the problem might just Go Away if you didn't have those there, and you really ought to use constants for that sort of thing. Put a log statement in yourRecipeServiceconstructor to see whether the bean is being instantiated at all; that will help you determine whether it's a finding-the-class problem or a graph-resolution problem. - chrylis -cautiouslyoptimistic-