Alexey Zvolinskiy

About Alexey Zvolinskiy

Alexey is a test developer with solid experience in automation of web-applications using Java, TestNG and Selenium. He is so much into QA that even after work he provides training courses for junior QA engineers.

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.

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

          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

          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

          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

          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:

...
<h1>Home page</h1>
<p>
${message}<br>
<a href="${pageContext.request.contextPath}/team/add.html">Add new team</a><br>
<a href="${pageContext.request.contextPath}/team/list.html">Team list</a><br>
</p>
...

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

          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:

...
<h1>Add team page</h1>
<p>Here you can add a new team.</p>
<form:form method="POST" commandname="team" action="${pageContext.request.contextPath}/team/add/process.html">
<table>
<tbody>
	<tr>
		<td>Name:</td>
		<td><form:input path="name"></form:input></td>
	</tr>
	<tr>
		<td>Rating:</td>
		<td><form:input path="rating"></form:input></td>
	</tr>
	<tr>
		<td><input value="Add" type="submit"></td>
		<td></td>
	</tr>
</tbody>
</table>
</form:form>

<p><a href="${pageContext.request.contextPath}/index.html">Home page</a></p>
...

“List of teams” page:

...
<h1>List of teams</h1>
<p>Here you can see the list of the teams, edit them, remove or update.</p>
<c:foreach var="team" items="${teams}">
</c:foreach><table border="1px" cellpadding="0" cellspacing="0">
<thead>
<tr>
<th width="10%">id</th><th width="15%">name</th><th width="10%">rating</th><th width="10%">actions</th>
</tr>
</thead>
<tbody>
<tr>
	<td>${team.id}</td>
	<td>${team.name}</td>
	<td>${team.rating}</td>
	<td>
	<a href="${pageContext.request.contextPath}/team/edit/${team.id}.html">Edit</a><br>
	<a href="${pageContext.request.contextPath}/team/delete/${team.id}.html">Delete</a><br>
	</td>
</tr>

</tbody>
</table>

<p><a href="${pageContext.request.contextPath}/index.html">Home page</a></p>
...

“Edit team” page:

...
<h1>Edit team page</h1>
<p>Here you can edit the existing team.</p>
<p>${message}</p>
<form:form method="POST" commandname="team" action="${pageContext.request.contextPath}/team/edit/${team.id}.html">
<table>
<tbody>
	<tr>
		<td>Name:</td>
		<td><form:input path="name"></form:input></td>
	</tr>
	<tr>
		<td>Rating:</td>
		<td><form:input path="rating"></form:input></td>
	</tr>
	<tr>
		<td><input value="Edit" type="submit"></td>
		<td></td>
	</tr>
</tbody>
</table>
</form:form>

<p><a href="${pageContext.request.contextPath}/index.html">Home page</a></p>
...

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.
 

Do you want to know how to develop your skillset to become a Java Rockstar?

Subscribe to our newsletter to start Rocking right now!

To get you started we give you two of our best selling eBooks for FREE!

JPA Mini Book

Learn how to leverage the power of JPA in order to create robust and flexible Java applications. With this Mini Book, you will get introduced to JPA and smoothly transition to more advanced concepts.

JVM Troubleshooting Guide

The Java virtual machine is really the foundation of any Java EE platform. Learn how to master it with this advanced guide!

Given email address is already subscribed, thank you!
Oops. Something went wrong. Please try again later.
Please provide a valid email address.
Thank you, your sign-up request was successful! Please check your e-mail inbox.
Please complete the CAPTCHA.
Please fill in the required fields.

15 Responses to "Spring MVC + Hibernate + Maven: CRUD operations example"

  1. I’ll try to start from the beginning.
    1. Entity should have equals, hashCode and toString. If you omit it – mention it. There are lot of less experienced readers who should be aware of good style.
    2. Nobody write repositories for JPA there days – we have Spring Data to do this for us. So it is a waste of time.
    3. If you do not have a business logic in your service – it is better to use Repository in the controller than
    4. LinkController – @RequestMapping(value={“/”,”/index”})
    5. TeamController:
    – validation is missing
    – addingTeam method should have POST in @RequestMapping
    – after adding/editing the one should use redirect to avoid accidental double form submit on refresh
    – no check if there is id provided in the path
    – you should use FlashAttributes ot RedirectAttributes for the success messages and NOT the model, errors should go in there

  2. Nilam Sari says:

    Hi, I have found that your article is really helpful. I am writing a guide for a friend who wish to learn about spring + hibernate stuff. I hope you don’t mind I share this article by providing the link in my blog and forked the specified github repo. Regards and thanks.

  3. May Mee Tun says:

    I have developed a project on eclipse according to this, but Maven CRUD function can’t run properly with my projects. is there any jar file to be added to the library or any more reason that I can test to continue.

  4. pavan says:

    Why other jsp page for editing. you can use input page for editing also. is it good or not?

  5. aBeginner says:

    Hi,
    I’m beginning with spring mvc + hibernate + maven. I download this project and I have some issues. Thus I can’t launch app with eclipse.
    When I tried to create myself, in pom.xml there is this error:
    Missing artifact org.javassist:javassist:jar:3.18.1-GA

  6. tolga says:

    i hate that everybody uses mysql because the samples they have looked based with it. Postgre is much better..

  7. Luiz Filho says:

    Hi, I downloaded your project in github, but it doesn’t work, show error 404.

    • Bill says:

      I got 404, too. Have you found the solution? I think we just visit the wrong URL, but what is the correct ones? Tried to fix for hours, but still have not found solution.

  8. Valentín says:

    very good tutorial and excuse my English but is not very good. I’m just starting to learn spring and my question is, there will be some tutorial about config files like web.xml, datasource.xml or persistence-context.xml that you recommend??

  9. ganesh says:

    Getting following Exception

    Caused by: org.springframework.beans.factory.BeanCreationException: Could not autowire field: private com.verse.service.TeamService com.vers

  10. pawan kumar says:

    It is very helpful to me .

  11. byanjati says:

    take a look at http://dtr-trading.blogspot.com/2014/02/spring-mvc-4-and-hibernate-4.html , compared with this article , i think this tutorial is not completed yet. :/ cause i got an error at running this project on my tomcat server.

Leave a Reply


4 × = twenty



Java Code Geeks and all content copyright © 2010-2014, Exelixis Media Ltd | Terms of Use | Privacy Policy | Contact
All trademarks and registered trademarks appearing on Java Code Geeks are the property of their respective owners.
Java is a trademark or registered trademark of Oracle Corporation in the United States and other countries.
Java Code Geeks is not connected to Oracle Corporation and is not sponsored by Oracle Corporation.
Do you want to know how to develop your skillset and become a ...
Java Rockstar?

Subscribe to our newsletter to start Rocking right now!

To get you started we give you two of our best selling eBooks for FREE!

Get ready to Rock!
You can download the complementary eBooks using the links below:
Close