2
votes

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>
2
How are you launching this? Is your @Service class getting component-scanned somehow? Post your context configuration. - chrylis -cautiouslyoptimistic-
I think, you do not have servlet defination in web.xml or it is not proper. can you post web.xml? - erencan
@chrylis I just updated the original post with some configuration files we use. Maybe this helps. - nsommer
@Nicktar Don't strip out package declarations as "irrelevant". They're probably the entire issue here. - chrylis -cautiouslyoptimistic-
I'll note that you're doing a lot of explicit naming of things (e.g., the @Service and @Resource names); 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 your RecipeService constructor 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-

2 Answers

0
votes

are your using <context:component-scan base-package=""/> ? because your @Service annotation is not recognized by container. please include the packages

0
votes

The problem is that you have a lot of Spring context files and you're not loading the right one(s). You have a root-context.xml defined and loaded from the web.xml (which I recommend against, even when using XML configuration; if you must, use an import from the specific context XML). Then for your servlet, you're loading servlet-context.xml, which is only component scanning your web package. You need for the context you point Spring at in your web.xml to scan the base package; those app-context.xml and applicationContext.xml files aren't actually getting loaded anywhere.

My recommendation these days is to avoid XML configuration entirely if possible in favor of the JavaConfig system; I have a single main entry-point @Configuration class for my entire application that then component-scans for any other @Configurations.