Spring MVC + Hibernate + Maven: CRUD operations example

In this article I want to examine an example of Spring MVC + Hibernate + Maven usage. This set of technology implies basic knowledge of the domain area. So I will try to explain all essential moments in detail. The other things which are out of topic, will be provided with links to more detail sources. In the end of the post I will publish a link to GitHub.
Now you can try a new tutorial on the same theme but with Spring Data JPA.

The goal

Creation of the sample web application, based on Spring MVC, Hibernate, Maven. Interface will be HTML-based. The application will support all CRUD operations: create, read, update, delete. As usually I will use MySQL as a database. The application will be work with football clubs entities, so be ready that the tutorial will be in a sport direction.

Spring-MVC-Hibernate-project-structure

Preparations

I will need one table in the database, and here is a code for its creation:

CREATE TABLE `teams` (
  `id` int(6) NOT NULL AUTO_INCREMENT,
  `name` varchar(40) NOT NULL,
  `rating` int(6) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8;

This table will be represented in the application with the class:

@Entity
@Table(name="teams")
public class Team {
	
	@Id
	@GeneratedValue
	private Integer id;
	
	private String name;
	
	private Integer rating;
	
	public Integer getId() {
		return id;
	}
	public void setId(Integer id) {
		this.id = id;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public Integer getRating() {
		return rating;
	}
	public void setRating(Integer rating) {
		this.rating = rating;
	}

}

Then I need to create a new Maven Web Project in IDE (I use Eclipse). I will omit the details of creation, you can read about this in one of my articles about Maven Web Project creation. Here is a link to the pom.xml file.
The first important stop is WebAppConfig.java file, so let’s consider:

@Configuration
@ComponentScan("com.sprhib")
@EnableWebMvc
@EnableTransactionManagement
@PropertySource("classpath:application.properties")
public class WebAppConfig {
	
    private static final String PROPERTY_NAME_DATABASE_DRIVER = "db.driver";
    private static final String PROPERTY_NAME_DATABASE_PASSWORD = "db.password";
    private static final String PROPERTY_NAME_DATABASE_URL = "db.url";
    private static final String PROPERTY_NAME_DATABASE_USERNAME = "db.username";
	
    private static final String PROPERTY_NAME_HIBERNATE_DIALECT = "hibernate.dialect";
    private static final String PROPERTY_NAME_HIBERNATE_SHOW_SQL = "hibernate.show_sql";
    private static final String PROPERTY_NAME_ENTITYMANAGER_PACKAGES_TO_SCAN = "entitymanager.packages.to.scan";
    
	@Resource
	private Environment env;
	
	@Bean
	public DataSource dataSource() {
		DriverManagerDataSource dataSource = new DriverManagerDataSource();
		
		dataSource.setDriverClassName(env.getRequiredProperty(PROPERTY_NAME_DATABASE_DRIVER));
		dataSource.setUrl(env.getRequiredProperty(PROPERTY_NAME_DATABASE_URL));
		dataSource.setUsername(env.getRequiredProperty(PROPERTY_NAME_DATABASE_USERNAME));
		dataSource.setPassword(env.getRequiredProperty(PROPERTY_NAME_DATABASE_PASSWORD));
		
		return dataSource;
	}
	
	@Bean
	public LocalSessionFactoryBean sessionFactory() {
		LocalSessionFactoryBean sessionFactoryBean = new LocalSessionFactoryBean();
		sessionFactoryBean.setDataSource(dataSource());
		sessionFactoryBean.setPackagesToScan(env.getRequiredProperty(PROPERTY_NAME_ENTITYMANAGER_PACKAGES_TO_SCAN));
		sessionFactoryBean.setHibernateProperties(hibProperties());
		return sessionFactoryBean;
	}
	
	private Properties hibProperties() {
		Properties properties = new Properties();
		properties.put(PROPERTY_NAME_HIBERNATE_DIALECT, env.getRequiredProperty(PROPERTY_NAME_HIBERNATE_DIALECT));
		properties.put(PROPERTY_NAME_HIBERNATE_SHOW_SQL, env.getRequiredProperty(PROPERTY_NAME_HIBERNATE_SHOW_SQL));
		return properties;	
	}
	
	@Bean
	public HibernateTransactionManager transactionManager() {
		HibernateTransactionManager transactionManager = new HibernateTransactionManager();
		transactionManager.setSessionFactory(sessionFactory().getObject());
		return transactionManager;
	}
	
	@Bean
	public UrlBasedViewResolver setupViewResolver() {
		UrlBasedViewResolver resolver = new UrlBasedViewResolver();
		resolver.setPrefix("/WEB-INF/pages/");
		resolver.setSuffix(".jsp");
		resolver.setViewClass(JstlView.class);
		return resolver;
	}

}

At the start of the file you can see @EnableTransactionManagement, it enables Spring’s annotation-driven transaction management capability. Annotation @PropertySource(“classpath:application.properties”) – plugs in property file which located in the resource folder.
Pay your attention on three beans: transactionManager, sessionFactory, dataSource. These beans provide transaction management. For more information read my article about Hibernate functionality.

#DB properties:
db.driver=com.mysql.jdbc.Driver
db.url=jdbc:mysql://localhost:3306/hibnatedb
db.username=hibuser
db.password=root

#Hibernate Configuration:
hibernate.dialect=org.hibernate.dialect.MySQL5InnoDBDialect
hibernate.show_sql=true
entitymanager.packages.to.scan=com.sprhib.model

Thats all what is related to project preparation. Further I’m going to show you DAO and service layers.

DAO & Service layers

Here are DAOs and Services interfaces and implementations:

public interface TeamDAO {
	
	public void addTeam(Team team);
	public void updateTeam(Team team);
	public Team getTeam(int id);
	public void deleteTeam(int id);
	public List<Team> getTeams();

}

Implementation of the DAO interface:

@Repository
public class TeamDAOImpl implements TeamDAO {
	
	@Autowired
	private SessionFactory sessionFactory;
	
	private Session getCurrentSession() {
		return sessionFactory.getCurrentSession();
	}

	public void addTeam(Team team) {
		getCurrentSession().save(team);
	}

	public void updateTeam(Team team) {
		Team teamToUpdate = getTeam(team.getId());
		teamToUpdate.setName(team.getName());
		teamToUpdate.setRating(team.getRating());
		getCurrentSession().update(teamToUpdate);
		
	}

	public Team getTeam(int id) {
		Team team = (Team) getCurrentSession().get(Team.class, id);
		return team;
	}

	public void deleteTeam(int id) {
		Team team = getTeam(id);
		if (team != null)
			getCurrentSession().delete(team);
	}

	@SuppressWarnings("unchecked")
	public List<Team> getTeams() {
		return getCurrentSession().createQuery("from Team").list();
	}

}

Annotation @Repository Indicates that an annotated class is a “DAO”.

public interface TeamService {
	
	public void addTeam(Team team);
	public void updateTeam(Team team);
	public Team getTeam(int id);
	public void deleteTeam(int id);
	public List<Team> getTeams();

}

Implementation of the Service interface:

@Service
@Transactional
public class TeamServiceImpl implements TeamService {
	
	@Autowired
	private TeamDAO teamDAO;

	public void addTeam(Team team) {
		teamDAO.addTeam(team);		
	}

	public void updateTeam(Team team) {
		teamDAO.updateTeam(team);
	}

	public Team getTeam(int id) {
		return teamDAO.getTeam(id);
	}

	public void deleteTeam(int id) {
		teamDAO.deleteTeam(id);
	}

	public List<Team> getTeams() {
		return teamDAO.getTeams();
	}

}

Annotation @Service indicates that an annotated class is a “Service”. Annotation @Transactional describes transaction attributes on a method or class.

Controllers & JSPs

Since I’m going to cover all CRUD operations, this chapter will be a little bit long. I will start from the base controller, it resposible for the Home page:

@Controller
public class LinkController {
	
	@RequestMapping(value="/")
	public ModelAndView mainPage() {
		return new ModelAndView("home");
	}
	
	@RequestMapping(value="/index")
	public ModelAndView indexPage() {
		return new ModelAndView("home");
	}

}

It is simple enough, and here its JSP file:

...

Home page

${message}
Add new team
Team list

...

And here is a monster-class, the main controller of the application:

@Controller
public class TeamController {
	
	@Autowired
	private TeamService teamService;
	
	@RequestMapping(value="/team/add")
	public ModelAndView addTeamPage() {
		ModelAndView modelAndView = new ModelAndView("add-team-form");
		modelAndView.addObject("team", new Team());
		return modelAndView;
	}
	
	@RequestMapping(value="/team/add/process")
	public ModelAndView addingTeam(@ModelAttribute Team team) {
		
		ModelAndView modelAndView = new ModelAndView("home");
		teamService.addTeam(team);
		
		String message = "Team was successfully added.";
		modelAndView.addObject("message", message);
		
		return modelAndView;
	}
	
	@RequestMapping(value="/team/list")
	public ModelAndView listOfTeams() {
		ModelAndView modelAndView = new ModelAndView("list-of-teams");
		
		List<Team> teams = teamService.getTeams();
		modelAndView.addObject("teams", teams);
		
		return modelAndView;
	}
	
	@RequestMapping(value="/team/edit/{id}", method=RequestMethod.GET)
	public ModelAndView editTeamPage(@PathVariable Integer id) {
		ModelAndView modelAndView = new ModelAndView("edit-team-form");
		Team team = teamService.getTeam(id);
		modelAndView.addObject("team",team);
		return modelAndView;
	}
	
	@RequestMapping(value="/team/edit/{id}", method=RequestMethod.POST)
	public ModelAndView edditingTeam(@ModelAttribute Team team, @PathVariable Integer id) {
		
		ModelAndView modelAndView = new ModelAndView("home");
		
		teamService.updateTeam(team);
		
		String message = "Team was successfully edited.";
		modelAndView.addObject("message", message);
		
		return modelAndView;
	}
	
	@RequestMapping(value="/team/delete/{id}", method=RequestMethod.GET)
	public ModelAndView deleteTeam(@PathVariable Integer id) {
		ModelAndView modelAndView = new ModelAndView("home");
		teamService.deleteTeam(id);
		String message = "Team was successfully deleted.";
		modelAndView.addObject("message", message);
		return modelAndView;
	}

}

Almost all methods and request mappings are clear. But I want to underline that @RequestMapping for the editTeamPage() and edditingTeam() methods, contains different valuse for the method attribute.
And now it’s time to see JSPs for these mappings:

“Add new team” page:

...

Add team page

Here you can add a new team.

Name:
Rating:

Home page

...

“List of teams” page:

...

List of teams

Here you can see the list of the teams, edit them, remove or update.

idnameratingactions
${team.id} ${team.name} ${team.rating} Edit
Delete

Home page

...

“Edit team” page:

...

Edit team page

Here you can edit the existing team.

${message}

Name:
Rating:

Home page

...

And a screenshot of the “List of teams” page:

Spring-MVC-Hibernate-CRUD-example

Summary

Integration of several technologies is usually not easy work, so be patient to achieve a success in this. There isn’t a lot of sources in the post, so you can visit my GitHub to explore classes in which you are interested.

Share and Enjoy

  • Facebook
  • Twitter
  • Delicious
  • LinkedIn
  • StumbleUpon
  • Add to favorites
  • Email
  • RSS
  • enzo

    Thank you for this amazing tutorial.
    Actually I followed all step by step. I was stuck in the WebAppConfig.java :
    the “getRequiredProperty” cant be recognized by Eclipse.

    • Fruzenshtein

      Strange, because this tutorial works on machines of my friends.
      Looks like you missed something

      • enzo

        Me too I can’t run the App on my PC. I think it is due to the web.xml

        • enzo

          Actually I have a 404 error

          • Fruzenshtein

            Have you checked git repository with the tutorial?

  • enzo

    I ve checked the repository with the tutorial : the web.xml is quite empty. Is it normal ?

  • enzo

    What I noticed too is the abscence of Spring files configuration

  • clement

    Thank you for this amazing tutorial.
    Actually I’m a beginner in Hibernate. While trying to add new team or check the list of teams I have this error :
    Request processing failed; nested exception is org.hibernate.hql.internal.ast.QuerySyntaxException: Team is not mapped [from Team]

    I think it is due to the messing of hibernate mapping xml files ?

    • Fruzenshtein

      It seems that you don’t apply @Entity or @Table annotations to the Team class. Be more attentive, and try to compare my project from GitHub with your.

      Don’t forget to like our page on FaceBook

  • Anonymous

    If you edit a team,
    the id of Team object team is not set,
    either you modify your html with sending a id parameter or you modify yout controller with setting the id with the path variable…

    • Fruzenshtein

      Everything was checked before I posted the example, so it works as expected

      Try to explain more clear what actually doesn’t work

  • Anonymous

    Calling the part:

    @RequestMapping(value=”/team/edit/{id}”, method=RequestMethod.POST)
    public ModelAndView edditingTeam(@ModelAttribute Team team, @PathVariable Integer id) {

    ModelAndView modelAndView = new ModelAndView(“home”);

    teamService.updateTeam(team);

    String message = “Team was successfully edited.”;
    modelAndView.addObject(“message”, message);

    return modelAndView;
    }

    – the id of the @ModelAttribute object team is not set/null
    – the @PathVariable Integer id is not used in this method
    -> the result is a NullPointerException if you edit a team…

  • http://javasd.com Almir Campos

    Thank you for the great tutorial! I had downloaded the GitHub zip file and I’m using NetBeans for the development. Everything is working fine.

  • http://javasd.com Almir Campos

    One more observation: I added a team named alert(“Oops”); and the browser executed the JavaScript code. I know that your tutorial is not about front-end security. I suggest you add a few comments (not codes) about security in input fields. Congratulations once more for your excellent tutorial!

  • http://javasd.com Almir Campos

    One more suggestion: to provide a brief explanation about the “Initializer” class. Thank you.

  • Abhay Agarwal

    Hi
    thanks for setting up such a nice example about Hibernate and Spring integration.

    I have one query
    In updateTeam method of TeamDAOImpl , why we have created a new instance of Team class (teamToUpdate)?
    We could have written
    getCurrentSession().update(team); where team is an input reference parameter.
    Any specific reason to create a new object here ?

    Thanks
    Abhay

    • Fruzenshtein

      The main reason is that I assign the already persisted object to the ‘teamToUpdate’ via retrieving the team object by ‘getTeam’ method.
      Read more about the object states in Hibernate

  • Leo

    Ciao, great tutorial…
    i have a problem cause i cannot find the home page, i have alwais 404 error.
    what should i write after localhost8080?
    Thanks

    • Fruzenshtein

      1. You can select your project in Eclipse and press [Run] icon.
      2. You have to write the name of the project after the port 8080. E.g. localhost:8080/app-name

      • Leo

        thats what i’m doing :(
        maybe there is something wrong with the web.xml, i should define the servlet tag?

        • Fruzenshtein

          Leo, you don’t need the web.xml in this project. Because I use java-based configurations.

          Try to search on my blog: “CONTROLLER WITH JAVA-BASED CONFIG”

  • Paul

    I have a 400 error when I press Add button. 2hrs of looking for a fix:

    HTTP Status 400 –
    type Status report
    message
    description The request sent by the client was syntactically incorrect.

    • Fruzenshtein

      As you know I push to the GitHub only that projects which works well. So try to compare your code with my.

      • Paul

        The code placed here is a bit diferent from the one on GitHub, but its not a problem. I find out that the 400 error was caused by a Date field in my entity class and a YEAR datatype in my MySQL database, problably some kind of convert problem. Ive just removed the date parametr :]

        • Fruzenshtein

          Cool

          Be more attentive in the future

  • Richard

    Could you explain a bit more on how this works without a persistence.xml? Or is there another use case that would still require that configuration?

  • Alex

    Hi,
    great tutorial,

    I have one issue which somebody was mentioned before but there was no response(

    When we edit team everyting is ok. Then we submit the form via POST

    @RequestMapping(value=”/team/edit/{id}”, method=RequestMethod.POST)
    public ModelAndView edditingTeam(@ModelAttribute Team team, @PathVariable Integer id) {

    At this method we get team via @ModelAttribute. Seems everything should be ok, but the team object for some reasons lost his Id and we se Id=0(zero).
    That is why our updateTeam method falls with NullPointer.

    Any solution? I don`t think that we need to bind this id to a hidden field in jsp from.

    • Fruzenshtein

      I have made a checkout of the project from GitHub and tried to edit a team. Everything works. If you want to make an explicity assigning of id in the controller method, feel free to make this, anyway id variable present in the method’s arguments.

      • Alex

        If it works on our side it only means for me that you have team in the base with the id = 0. I don`t know another reasons.
        (@ModelAttribute Team team) makes instance of type Team from binding filels, and as we don’t have id in html it leaves it as default = 0.

        I solved this problem by adding

        to the edit-team-form.jsp

        Anyway I am very interested how it possible on your side

        Thanks in advance

        • Alex

          I ‘ve added form:hidden path=”id” to edit-team-form.jsp

  • Alex

    Cloned your project. Everthing works fine. Amazing.
    Only difference in configuration. My configuration was made via xml. pom files the same.

    • Karthik

      alex, how you cloned this project? is it possible to integrate git with eclipse and to download (checkout) this ? if yes, how to do it step by step pls…!

      r u using eclipse?

      • Alex

        Hi Karthik,
        It’s pretty easy to clone project from git.
        git clone git://github.com/Fruzenshtein/spr-mvc-hib.git.
        If you use eclipse you can set up m2e plugin, so you will be able to import maven project via pom file.

  • Karthik

    Im getting following errs during the journey of implementation…

    In Initializer.java & WebAppConfig.java…

    “Multiple markers at this line
    – The type org.springframework.beans.factory.support.BeanNameGenerator cannot be resolved. It is indirectly referenced from
    required .class files
    – The type org.springframework.beans.factory.annotation.Autowire cannot be resolved. It is indirectly referenced from required .class files
    – The type org.springframework.beans.factory.support.BeanNameGenerator cannot be resolved. It is indirectly referenced from
    required .class files “

    • Alex

      Just check dependencies from pom.xml at git source. Seems you have another versions of dependencies which will lead to these problems.

  • eb

    what is the url for running app?

  • eb

    how can run this application from tomcat in eclipse juno?i cant deploy it to tomcat 6.0.36
    i am using eclipse juno,tomcat 6.0.36 and j2me plugin.please help me,thank u.

  • Karthik

    Damn… Solved all issues after a long struggle! everything works properly! cool to work with Initializer & WebAppConfig…

  • firen

    Great tutorial, very well explained! Can you possibly explain how to integrate Ehcache into this example? All the tutorials I see online utilizes ehcache.xml but since you use webappconfig.java I was wondering what the proper way to do that would be.

    Thanks.

    • Fruzenshtein

      Thanks for the comment

      I think this is a good theme for a new topic. I’ll try to publish post about Ehcach in the nearest feature

  • a s

    also I am getting this error in jsp pages ,Multiple annotations found at this line:

    – javax.servlet cannot be resolved to a type

    – contextPath cannot be resolved as a member of

    request

    thanks

  • http://fruzenshtein.com/ Alex Zvolinskiy

    Try to google it, there is a special plugin for maven

  • Yusuf Ibr.

    its hard for beginner like me to follow your article, since you did’t put any information where (folder) I should put the code, or you have another article for beginner like me ? thanks

  • Fernando Quiroz

    hello alex, first thanks for the article !

    I followed every step, and also downloaded the source code from git.

    when I ran the project I throw the following error:

    HTTP Status 404 – / WebSpringHibernate /
    ————————————————– ——————————
    type Status report
    Message / spr-mvc-hib /
    description The requested resource (/ spr-mvc-hib /) is not available.
    ————————————————– ——————————
    Apache Tomcat/7.0.12

    may be missing an entry to web.xml?

    I do not know what is wrong.

    Thanks

  • marghi

    c’est super Merci infiniment, moi je veux intégrer le framework Tiles, mais je sais pas que dois-je ajouter au niveau de la class WebAppConfig.java ?

    • http://fruzenshtein.com/ Alex Zvolinskiy

      Please write in English, Ukrainian or Russian in any other language I can’t answer on the question
      Sorry

      • marghi

        Thank you very much it’s great, I want to integrate Tiles framework, but I do not know what should I add in the class WebAppConfig …

        • http://fruzenshtein.com/ Alex Zvolinskiy

          Oh, now I see what you want

          I will try to publish a tutorial in the nearest time about integration of Tiles into Spring MVC project

          This news will be in FaceBook group, so you can subscribe the Fruzenshtein’s Notes in the FaceBook

          • marghi

            thank you so much !

  • shamsuvs

    thanks

  • Ariel Duarte

    Thanks a lot man, it’s working perfectly!!

  • Yuzri Chiko

    thank you very much

  • Anil Kumar Pandey

    Its really great resource for spring with hibernate but I have only one doubt, How “Initializer” class is called first ?? because your web.xml file is empty and I am not able to get any reference which is calling the “Initializer class”

    • http://fruzenshtein.com/ Alex Zvolinskiy

      Look on the interface which Initializaer class implements

      • Anil Kumar Pandey

        The WebApplicationInitializer?? onStartup function call itself… am I right??

        • http://fruzenshtein.com/ Alex Zvolinskiy

          Yes

          • Anil Kumar Pandey

            Your code is successfully running but when I am trying to create another project (same as above just table fields are changed) then its not working and the server showing warning “WARNING: No mapping found for HTTP request with URI [/StudentManagement/] in DispacherServlet with name ‘dispacher’ “. Please let me know if am I doing something wrong. Thanks
            (I am using eclipse IDE with m2e plugin for creating new maven project.)

          • http://fruzenshtein.com/ Alex Zvolinskiy

            Try to clean up Tomcat work directory and then redeploy the application

  • Anil Kumar Pandey

    Can you give me some idea to create same project as a SPA(Single page application) fully ajax driven using json request and responses??

  • Sebastian Assa

    Hello… I need a example of crud application with spring mvc, oracle database connection and jbdctemplate, do you help me?

    • ssss

      Pay me ;)

  • Марио Ѓурчески

    How to import this project, in eclipse when i want to import says ” No projects are found to import”… please tell me what to do!

  • may ibrahim

    i cant find the link to gitlab

  • Karthik Srinivasan

    Hi Alex, Thanks for the tutorial. I am getting status 404 which says /WEB-INF/pages/home.jsp, the requested resources is missing. Could you please shed some light on solving this issue.

    • Karthik Srinivasan

      I added the files to web-content folder it works. However I am not able to access any of my css and js files. Any suggestions on this?

      • http://fruzenshtein.com/ Alex Zvolinskiy

        Try to read my article about resources

        http://fruzenshtein.com/spring-mvc-resources/

        • Karthik Srinivasan

          Thanks for your reply, very much appreciated.

        • Karthik Srinivasan

          Hi Alex, that link solved my previous issue. I have some similar issue right now. I have two different .js file in same location, one of them is getting loaded, whereas the other is not. And I am getting resources not available error. Any suggestions regarding this one??

      • http://byanjati.tumblr.com Byan

        i’m questioning about Alex project , that project is not having web-content folder and still running , for me , i added web-content folder to run it on server and works , if i delete web-content folder , i’ll get 404 status

  • ganesh

    Getting following Exception
    org.springframework.beans.factory.BeanCreationException: Error creating bean with name ‘teamController': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private com.verse.service.TeamService com.verse.controller.TeamController.teamService; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No matching bean of type [com.verse.service.TeamService] 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)}

  • Bill

    Hi Alex, I imported your project in eclipse and tomcat started successfully, but I got 404 error when trying to visit the project. I tried many times, but still can not find reason. Would you give me some hint, please? Thank you.

    • http://fruzenshtein.com/ Alex Zvolinskiy

      Try to clean up Tomcat work directory and then redeploy the application

  • http://code-away.tumblr.com/ Olayinka

    My semester project is based on this tutorial. Than you very much.

  • Eric

    Thank you so much for this tutorial. I used a similar structure as this in my project with a products website and it runs flawlessly.