Java Spring Hibernate Rest Example
Posted on September 29, 2017
What is REST? REST stands for Representational State Transfer, which is an architecture style for designing distributed systems. A web service based on the REST architecture is referred as RESTful web services.
CRUD stands for Create, Read, Update and Delete, which refers to the four operations on persistence storage.
RESTful service uses the following HTTP methods to map the HTTP request to CRUD operations.
| HTTP Method | CRUD Operation | Description |
|---|---|---|
| POST | Create | Create a new resource ( equivalent to sql INSERT statement) |
| GET | Read | Retrieve a resource ( equivalent to sql SELECT statement) |
| PUT/PATCH | Update | Update or modify a resource ( equivalent to sql UPDATE statement) |
| DELETE | Delete | Delete a resource ( equivalent to sql DELETE statement) |
In this post, I will show you how to create CRUD operations using the Spring MVC RESTful web service and Hibernate ORM framework.
Tools and technologies used for this application are-
- Spring Web MVC 4.3.10.RELEASE
- Spring OXM 4.3.10.RELEASE
- Jackson API 2.8.7
- Hibernate 5.2.11.Final
- c3p0 0.9.5.2
- MySQL 5.7.12
- Java SE 1.8
- Maven 3.3.9
- Eclipse Neon.3
- Apache Tomcat 7.0.47
Project structure
Review the following Spring MVC web application project structure.
Related - How to create a web project using maven build tool in eclipse IDE.
Jar dependencies
Editpom.xml file of your maven project and add the following dependencies in it.
<dependencies> <!-- Spring MVC Dependency --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>4.3.10.RELEASE</version> </dependency> <!-- Spring ORM --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-orm</artifactId> <version>4.3.10.RELEASE</version> </dependency> <!-- Hibernate ORM --> <dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-core</artifactId> <version>5.2.11.Final</version> </dependency> <!-- Hibernate-C3P0 Integration --> <dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-c3p0</artifactId> <version>5.2.11.Final</version> </dependency> <!-- c3p0 --> <dependency> <groupId>com.mchange</groupId> <artifactId>c3p0</artifactId> <version>0.9.5.2</version> </dependency> <!-- Mysql Connector --> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>6.0.5</version> </dependency> <!-- Jackson API for JSON --> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <version>2.8.7</version> </dependency> <!-- Servlet Dependency --> <dependency> <groupId>javax.servlet</groupId> <artifactId>javax.servlet-api</artifactId> <version>3.1.0</version> <scope>provided</scope> </dependency> </dependencies> Model or Entity class
Create a simple @Entity class undercom.boraji.tutorial.spring.model package.
Book.java
package com.boraji.tutorial.spring.model; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; @Entity(name = "Book") public class Book { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; private String title; private String author; //Getter and Setter methods } Controller class
Create a@RestController class and annotate the handler methods with @PostMapping, @GetMapping, @PutMapping and @DeleteMapping annotations to map thePOST, GET, PUT and DELETE requests respectively.
BookController.java
package com.boraji.tutorial.spring.controller; import java.util.List; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.DeleteMapping; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.PutMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RestController; import com.boraji.tutorial.spring.model.Book; import com.boraji.tutorial.spring.service.BookService; @RestController public class BookController { @Autowired private BookService bookService; /*---Add new book---*/ @PostMapping("/book") public ResponseEntity<?> save(@RequestBody Book book) { long id = bookService.save(book); return ResponseEntity.ok().body("New Book has been saved with ID:" + id); } /*---Get a book by id---*/ @GetMapping("/book/{id}") public ResponseEntity<Book> get(@PathVariable("id") long id) { Book book = bookService.get(id); return ResponseEntity.ok().body(book); } /*---get all books---*/ @GetMapping("/book") public ResponseEntity<List<Book>> list() { List<Book> books = bookService.list(); return ResponseEntity.ok().body(books); } /*---Update a book by id---*/ @PutMapping("/book/{id}") public ResponseEntity<?> update(@PathVariable("id") long id, @RequestBody Book book) { bookService.update(id, book); return ResponseEntity.ok().body("Book has been updated successfully."); } /*---Delete a book by id---*/ @DeleteMapping("/book/{id}") public ResponseEntity<?> delete(@PathVariable("id") long id) { bookService.delete(id); return ResponseEntity.ok().body("Book has been deleted successfully."); } } Data Access Object (DAO) class
Create@Repository classes undercom.boraji.tutorial.spring.dao package as follows.
BookDao.java
package com.boraji.tutorial.spring.dao; import java.util.List; import com.boraji.tutorial.spring.model.Book; public interface BookDao { long save(Book book); Book get(long id); List<Book> list(); void update(long id, Book book); void delete(long id); } BookDaoImp.java
package com.boraji.tutorial.spring.dao; import java.util.List; import javax.persistence.criteria.CriteriaBuilder; import javax.persistence.criteria.CriteriaQuery; import javax.persistence.criteria.Root; 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.boraji.tutorial.spring.model.Book; @Repository public class BookDaoImp implements BookDao { @Autowired private SessionFactory sessionFactory; @Override public long save(Book book) { sessionFactory.getCurrentSession().save(book); return book.getId(); } @Override public Book get(long id) { return sessionFactory.getCurrentSession().get(Book.class, id); } @Override public List<Book> list() { Session session = sessionFactory.getCurrentSession(); CriteriaBuilder cb = session.getCriteriaBuilder(); CriteriaQuery<Book> cq = cb.createQuery(Book.class); Root<Book> root = cq.from(Book.class); cq.select(root); Query<Book> query = session.createQuery(cq); return query.getResultList(); } @Override public void update(long id, Book book) { Session session = sessionFactory.getCurrentSession(); Book book2 = session.byId(Book.class).load(id); book2.setTitle(book.getTitle()); book2.setAuthor(book.getAuthor()); session.flush(); } @Override public void delete(long id) { Session session = sessionFactory.getCurrentSession(); Book book = session.byId(Book.class).load(id); session.delete(book); } } Service class
Create@Service classes undercom.boraji.tutorial.spring.service package as follows.
BookService.java
package com.boraji.tutorial.spring.service; import java.util.List; import com.boraji.tutorial.spring.model.Book; public interface BookService { long save(Book book); Book get(long id); List<Book> list(); void update(long id, Book book); void delete(long id); } BookServiceImp.java
package com.boraji.tutorial.spring.service; import java.util.List; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import com.boraji.tutorial.spring.dao.BookDao; import com.boraji.tutorial.spring.model.Book; @Service @Transactional(readOnly = true) public class BookServiceImp implements BookService { @Autowired private BookDao bookDao; @Transactional @Override public long save(Book book) { return bookDao.save(book); } @Override public Book get(long id) { return bookDao.get(id); } @Override public List<Book> list() { return bookDao.list(); } @Transactional @Override public void update(long id, Book book) { bookDao.update(id, book); } @Transactional @Override public void delete(long id) { bookDao.delete(id); } } Spring configuration
Create a web@Configuration class annotated with@EnableWebMvc and@ComponentScan as follows.
WebConfig.java
package com.boraji.tutorial.spring.config; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation.EnableWebMvc; import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter; @Configuration @EnableWebMvc @ComponentScan(basePackages = { "com.boraji.tutorial.spring.controller" }) public class WebConfig extends WebMvcConfigurerAdapter { } Create another@Configuration class to configure the Hibernate ORM with Spring MVC application. Annotate this class with@EnableTransactionManagement annotation to enable the transaction management.
AppConfig.java
package com.boraji.tutorial.spring.config; import java.util.Properties; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.ComponentScans; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.PropertySource; import org.springframework.core.env.Environment; import org.springframework.orm.hibernate5.HibernateTransactionManager; import org.springframework.orm.hibernate5.LocalSessionFactoryBean; import org.springframework.transaction.annotation.EnableTransactionManagement; import static org.hibernate.cfg.Environment.*; @Configuration @PropertySource("classpath:db.properties") @EnableTransactionManagement @ComponentScans(value = { @ComponentScan("com.boraji.tutorial.spring.dao"), @ComponentScan("com.boraji.tutorial.spring.service") }) public class AppConfig { @Autowired private Environment env; @Bean public LocalSessionFactoryBean getSessionFactory() { LocalSessionFactoryBean factoryBean = new LocalSessionFactoryBean(); Properties props = new Properties(); // Setting JDBC properties props.put(DRIVER, env.getProperty("mysql.driver")); props.put(URL, env.getProperty("mysql.url")); props.put(USER, env.getProperty("mysql.user")); props.put(PASS, env.getProperty("mysql.password")); // Setting Hibernate properties props.put(SHOW_SQL, env.getProperty("hibernate.show_sql")); props.put(HBM2DDL_AUTO, env.getProperty("hibernate.hbm2ddl.auto")); // Setting C3P0 properties props.put(C3P0_MIN_SIZE, env.getProperty("hibernate.c3p0.min_size")); props.put(C3P0_MAX_SIZE, env.getProperty("hibernate.c3p0.max_size")); props.put(C3P0_ACQUIRE_INCREMENT, env.getProperty("hibernate.c3p0.acquire_increment")); props.put(C3P0_TIMEOUT, env.getProperty("hibernate.c3p0.timeout")); props.put(C3P0_MAX_STATEMENTS, env.getProperty("hibernate.c3p0.max_statements")); factoryBean.setHibernateProperties(props); factoryBean.setPackagesToScan("com.boraji.tutorial.spring.model"); return factoryBean; } @Bean public HibernateTransactionManager getTransactionManager() { HibernateTransactionManager transactionManager = new HibernateTransactionManager(); transactionManager.setSessionFactory(getSessionFactory().getObject()); return transactionManager; } } Create a db.properties file under src/main/resources folder to define the MySQL database, hibernate and c3p0 connection pooling properties as follows.
db.properties
# MySQL properties mysql.driver=com.mysql.cj.jdbc.Driver mysql.url=jdbc:mysql://localhost:3306/BORAJI mysql.user=root mysql.password=admin # Hibernate properties hibernate.show_sql=true hibernate.hbm2ddl.auto=update #C3P0 properties hibernate.c3p0.min_size=5 hibernate.c3p0.max_size=20 hibernate.c3p0.acquire_increment=1 hibernate.c3p0.timeout=1800 hibernate.c3p0.max_statements=150 Servlet container initialization
Create a MyWebAppInitializer class, which will replace our traditional web.xml, to initialize the Servlet container.
MyWebAppInitializer.java
package com.boraji.tutorial.spring.config; import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer; public class MyWebAppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer { @Override protected Class<?>[] getRootConfigClasses() { return new Class[] { AppConfig.class }; } @Override protected Class<?>[] getServletConfigClasses() { return new Class[] { WebConfig.class }; } @Override protected String[] getServletMappings() { return new String[] { "/" }; } } TheAbstractAnnotationConfigDispatcherServletInitializer class, implements theWebApplicationInitializer, is implemented in Servlet 3.0+ environments in order to configure theServletContext programmatically.
Build + Deploy + Run application
Use the following maven commands to build, deploy and run Tomcat server.
mvn clean install (This command triggers war packaging)
mvn tomcat7:run (This command run embedded tomcat and deploy war file automatically)
You can refer this link to learn how to run the above commands in Eclipse IDE.
In this example, we will use the POSTMAN tool (A Chrome App) to test our RESTful web services.
POST request -http://localhost:8080/book
GET request -http://localhost:8080/book/1
GET request (retrieve all books) -http://localhost:8080/book
PUT request -http://localhost:8080/book/2
DELETE request -http://localhost:8080/book/1
Source: https://www.boraji.com/spring-mvc-4-hibernate-5-restful-crud-operations-example
0 Response to "Java Spring Hibernate Rest Example"
Post a Comment