Spring Data CrudRepository Example
November 15, 2017
This page will walk through Spring Data CrudRepository
example. It provides generic CRUD operation on a repository for a specific type. CrudRepository
is a Spring data interface and to use it we need to create our interface by extending CrudRepository
for a specific type. Spring provides CrudRepository
implementation class automatically at runtime. It contains methods such as save
, findById
, delete
, count
etc. If we want to add extra methods, we need to declare it in our interface. All the methods of CrudRepository
are annotated with @Transactional
in implementation class by default at runtime. In our example we will create a REST application to create, read, update and delete articles using JavaConfig as well as XML configuration. We will also write client code using RestTemplate
to test our CRUD application. Now find the complete example step by step.
Contents
- 1. Technologies Used
- 2. Gradle and Maven used in Project
- 3. CrudRepository Interface
- 4. Steps to Use CrudRepository
- 5. Custom Repository Methods
- 6. @Transactional with CrudRepository
- 7. Spring Data CrudRepository + JPA + Hibernate Example using JavaConfig
- 8. Spring Data CrudRepository + JPA + Hibernate Example using XML Configuration
- 9. Client Code with RestTemplate to Test CRUD Application
- 10. Run and Test Application
- 11. References
- 12. Download Source Code
1. Technologies Used
Find the technologies being used in our example.1. Java 9
2. Spring 5.0.5.RELEASE
3. Spring Boot 2.0.1.RELEASE
4. Gradle 4.3.1
5. Maven 3.5.2
6. Tomcat 8.5
7. MySQL 5.5
8. Eclipse Oxygen
2. Gradle and Maven used in Project
Find the Gradle file to build the project.build.gradle
apply plugin: 'java' apply plugin: 'eclipse' apply plugin: 'war' war.archiveName 'spring-app.war' sourceCompatibility = 9 repositories { mavenCentral() } dependencies { compile 'org.springframework.boot:spring-boot-starter-web:2.0.1.RELEASE' compile 'org.springframework.boot:spring-boot-starter-data-jpa:2.0.1.RELEASE' compile 'mysql:mysql-connector-java:6.0.5' compile 'org.apache.commons:commons-dbcp2:2.1.1' compile 'javax.xml.bind:jaxb-api:2.3.0' providedRuntime 'org.springframework.boot:spring-boot-starter-tomcat:2.0.1.RELEASE' }
pom.xml
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.concretepage</groupId> <artifactId>spring-demo</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>war</packaging> <name>Spring</name> <description>Spring Demo Project</description> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.0.1.RELEASE</version> <relativePath/> </parent> <properties> <context.path>spring-app</context.path> <java.version>9</java.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>6.0.5</version> </dependency> <dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-dbcp2</artifactId> <version>2.1.1</version> </dependency> <dependency> <groupId>javax.xml.bind</groupId> <artifactId>jaxb-api</artifactId> <version>2.3.0</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-tomcat</artifactId> <scope>provided</scope> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-war-plugin</artifactId> <version>3.2.0</version> <configuration> <warName>${context.path}</warName> </configuration> </plugin> </plugins> </build> </project>
3. CrudRepository Interface
CrudRepository
is an interface and extends Spring data Repository
interface. CrudRepository
provides generic CRUD operation on a repository for a specific type. It has generic methods for CRUD operation. To use CrudRepository
we have to create our interface and extend CrudRepository
. We need not to implement our interface, its implementation will be created automatically at runtime. Find some of CrudRepository
methods.
<S extends T> S save(S entity)
: Saves and updates the current entity and returns that entity.
Optional<T> findById(ID primaryKey)
: Returns the entity for the given id.
Iterable<T> findAll()
: Returns all entities.
long count()
: Returns the count.
void delete(T entity)
: Deletes the given entity.
boolean existsById(ID primaryKey)
: Checks if the entity for the given id exists or not.
CrudRepository
has subinterface as PagingAndSortingRepository
that provide additional methods to retrieve entities using the pagination and sorting abstraction.
4. Steps to Use CrudRepository
To useCrudRepository
in our Spring data application we need to enable JPA repositories using JavaConfig or XML configuration. We need to create an interface implementing CrudRepository
and then all are set to use it. Let us discuss step wise how to use CrudRepository
in our Spring data application.
4.1 Create an Interface extending CrudRepository
In our example we will perform CRUD operations on article data for demo. So I will create an interface for article extendingCrudRepository
as following.
public interface ArticleRepository extends CrudRepository<Article, Long> { }
4.2 Configure JPA repositories
We need to configure JPA repository location so that Spring data can find our all defined repository interfaces that are extendingCrudRepository
. We need to configure package name of our repository classes. Here we will provide JPA repository configuration using JavaConfig as well as XML configuration.
a. JavaConfig
We need to annotate our JavaConfig class with
@EnableJpaRepositories
and pass repository package name. Find the code snippet.
@Configuration @EnableJpaRepositories("com.concretepage.repository") public class JPAConfig { }
In XML configuration we will configure JPA repository as following.
<?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:jpa="http://www.springframework.org/schema/data/jpa" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/data/jpa http://www.springframework.org/schema/data/jpa/spring-jpa.xsd"> <jpa:repositories base-package="com.concretepage.repository"/> </beans>
4.3 Instantiate and Use CrudRepository
To instantiate ourArticleRepository
that has extended CrudRepository
, we can use dependency injection.
public class ArticleService { @Autowired private ArticleRepository articleRepository; ------ }
CrudRepository
. Find the example for some of its methods.
a. Create and Update:
Article savedArticle = articleRepository.save(article);
Article obj = articleRepository.findById(articleId).get(); Iterable<Article> articles = articleRepository.findAll();
articleRepository.delete(article);
5. Custom Repository Methods
CrudRepository
provides methods for generic CRUD operation and if we want to add custom methods in our interface that has extended CrudRepository
, we can add in following ways.
a. We can start our query method names with
find...By
, read...By
, query...By
, count...By
, and get...By
. Before By
we can add expression such as Distinct
. After By
we need to add property names of our entity.
b. To get data on the basis of more than one property we can concatenate property names using
And
and Or
while creating method names.
c. If we want to use completely custom name for our method, we can use
@Query
annotation to write query.
Find the code snippet that is using the sample method name for the above scenarios.
public interface ArticleRepository extends CrudRepository<Article, Long> { List<Article> findByTitle(String title); List<Article> findDistinctByCategory(String category); List<Article> findByTitleAndCategory(String title, String category); @Query("SELECT a FROM Article a WHERE a.title=:title and a.category=:category") List<Article> fetchArticles(@Param("title") String title, @Param("category") String category); }
6. @Transactional with CrudRepository
CRUD methods ofCrudRepository
are transactional by default. They are annotated with @Transactional
annotation with default settings in implementation class at runtime. For reading operation readOnly
flag is set to true
. To override default transactional settings of any CrudRepository
methods we need to override that method in our interface and annotate with @Transactional
using required configurations. Find the example.
public interface ArticleRepository extends CrudRepository<Article, Long> { @Override @Transactional(timeout = 8) Iterable<Article> findAll(); }
timeout
as 8 seconds to execute query without readOnly
flag for findAll()
method.
7. Spring Data CrudRepository + JPA + Hibernate Example using JavaConfig
Find the project structure of our project using JavaConfig.
Database Table
CREATE DATABASE IF NOT EXISTS `concretepage`; USE `concretepage`; CREATE TABLE IF NOT EXISTS `articles` ( `article_id` bigint(5) NOT NULL AUTO_INCREMENT, `title` varchar(200) NOT NULL, `category` varchar(100) NOT NULL, PRIMARY KEY (`article_id`) ) ENGINE=InnoDB; INSERT INTO `articles` (`article_id`, `title`, `category`) VALUES (1, 'Java Concurrency', 'Java'), (2, 'Spring Boot Getting Started', 'Spring Boot'), (3, 'Lambda Expressions Java 8 Example', 'Java 8');
ArticleRepository.java
package com.concretepage.repository; import java.util.List; import org.springframework.data.repository.CrudRepository; import com.concretepage.entity.Article; public interface ArticleRepository extends CrudRepository<Article, Long> { List<Article> findByTitle(String title); List<Article> findDistinctByCategory(String category); List<Article> findByTitleAndCategory(String title, String category); }
package com.concretepage.entity; import java.io.Serializable; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.Table; @Entity @Table(name="articles") public class Article implements Serializable { private static final long serialVersionUID = 1L; @Id @GeneratedValue(strategy=GenerationType.AUTO) @Column(name="article_id") private long articleId; @Column(name="title") private String title; @Column(name="category") private String category; public long getArticleId() { return articleId; } public void setArticleId(long articleId) { this.articleId = articleId; } public String getTitle() { return title; } public void setTitle(String title) { this.title = title; } public String getCategory() { return category; } public void setCategory(String category) { this.category = category; } }
package com.concretepage.service; import java.util.List; import com.concretepage.entity.Article; public interface IArticleService { List<Article> getAllArticles(); Article getArticleById(long articleId); boolean addArticle(Article article); void updateArticle(Article article); void deleteArticle(int articleId); }
package com.concretepage.service; import java.util.ArrayList; import java.util.List; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import com.concretepage.entity.Article; import com.concretepage.repository.ArticleRepository; @Service public class ArticleService implements IArticleService { @Autowired private ArticleRepository articleRepository; @Override public Article getArticleById(long articleId) { Article obj = articleRepository.findById(articleId).get(); return obj; } @Override public List<Article> getAllArticles(){ List<Article> list = new ArrayList<>(); articleRepository.findAll().forEach(e -> list.add(e)); return list; } @Override public synchronized boolean addArticle(Article article){ List<Article> list = articleRepository.findByTitleAndCategory(article.getTitle(), article.getCategory()); if (list.size() > 0) { return false; } else { articleRepository.save(article); return true; } } @Override public void updateArticle(Article article) { articleRepository.save(article); } @Override public void deleteArticle(int articleId) { articleRepository.delete(getArticleById(articleId)); } }
JPAConfig.java
package com.concretepage.config; import java.util.Properties; import javax.sql.DataSource; import org.apache.commons.dbcp2.BasicDataSource; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.PropertySource; import org.springframework.core.env.Environment; import org.springframework.data.jpa.repository.config.EnableJpaRepositories; import org.springframework.orm.jpa.JpaTransactionManager; import org.springframework.orm.jpa.JpaVendorAdapter; import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean; import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter; import org.springframework.transaction.PlatformTransactionManager; import org.springframework.transaction.annotation.EnableTransactionManagement; @Configuration @EnableTransactionManagement @EnableJpaRepositories("com.concretepage.repository") @PropertySource("classpath:database.properties") public class JPAConfig { @Autowired private Environment env; @Bean(name="entityManagerFactory") public LocalContainerEntityManagerFactoryBean getEntityManagerFactoryBean() { LocalContainerEntityManagerFactoryBean lcemfb = new LocalContainerEntityManagerFactoryBean(); lcemfb.setJpaVendorAdapter(getJpaVendorAdapter()); lcemfb.setDataSource(getDataSource()); lcemfb.setPersistenceUnitName("myJpaPersistenceUnit"); lcemfb.setPackagesToScan("com.concretepage.entity"); lcemfb.setJpaProperties(jpaProperties()); return lcemfb; } @Bean public JpaVendorAdapter getJpaVendorAdapter() { JpaVendorAdapter adapter = new HibernateJpaVendorAdapter(); return adapter; } @Bean public DataSource getDataSource() { BasicDataSource dataSource = new BasicDataSource(); dataSource.setDriverClassName(env.getProperty("database.driverClassName")); dataSource.setUrl(env.getProperty("database.url")); dataSource.setUsername(env.getProperty("database.username")); dataSource.setPassword(env.getProperty("database.password")); return dataSource; } @Bean(name="transactionManager") public PlatformTransactionManager txManager(){ JpaTransactionManager jpaTransactionManager = new JpaTransactionManager( getEntityManagerFactoryBean().getObject()); return jpaTransactionManager; } private Properties jpaProperties() { Properties properties = new Properties(); properties.put("hibernate.dialect", env.getProperty("hibernate.dialect")); properties.put("hibernate.show_sql", env.getProperty("hibernate.show_sql")); properties.put("hibernate.format_sql", env.getProperty("hibernate.format_sql")); properties.put("hibernate.id.new_generator_mappings", env.getProperty("hibernate.id.new_generator_mappings")); return properties; } }
package com.concretepage.config; import java.util.List; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; import org.springframework.http.converter.HttpMessageConverter; import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder; import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter; import org.springframework.web.servlet.config.annotation.EnableWebMvc; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; @Configuration @ComponentScan("com.concretepage") @EnableWebMvc public class AppConfig implements WebMvcConfigurer { @Override public void configureMessageConverters(List<HttpMessageConverter<?>> converters) { Jackson2ObjectMapperBuilder builder = new Jackson2ObjectMapperBuilder(); builder.indentOutput(true); converters.add(new MappingJackson2HttpMessageConverter(builder.build())); } }
package com.concretepage.config; import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer; public class WebAppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer { @Override protected Class<?>[] getRootConfigClasses() { return new Class[] { AppConfig.class }; } @Override protected Class<?>[] getServletConfigClasses() { return null; } @Override protected String[] getServletMappings() { return new String[]{ "/" }; } }
database.driverClassName=com.mysql.cj.jdbc.Driver database.url=jdbc:mysql://localhost:3306/concretepage database.username=root database.password=cp hibernate.dialect = org.hibernate.dialect.MySQLDialect hibernate.show_sql = true hibernate.format_sql = true hibernate.id.new_generator_mappings = false
package com.concretepage.controller; import java.util.List; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.stereotype.Controller; 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.RequestMapping; import org.springframework.web.util.UriComponentsBuilder; import com.concretepage.entity.Article; import com.concretepage.service.IArticleService; @Controller @RequestMapping("user") public class ArticleController { @Autowired private IArticleService articleService; @GetMapping("article/{id}") public ResponseEntity<Article> getArticleById(@PathVariable("id") Integer id) { Article article = articleService.getArticleById(id); return new ResponseEntity<Article>(article, HttpStatus.OK); } @GetMapping("articles") public ResponseEntity<List<Article>> getAllArticles() { List<Article> list = articleService.getAllArticles(); return new ResponseEntity<List<Article>>(list, HttpStatus.OK); } @PostMapping("article") public ResponseEntity<Void> addArticle(@RequestBody Article article, UriComponentsBuilder builder) { boolean flag = articleService.addArticle(article); if (flag == false) { return new ResponseEntity<Void>(HttpStatus.CONFLICT); } HttpHeaders headers = new HttpHeaders(); headers.setLocation(builder.path("/article/{id}").buildAndExpand(article.getArticleId()).toUri()); return new ResponseEntity<Void>(headers, HttpStatus.CREATED); } @PutMapping("article") public ResponseEntity<Article> updateArticle(@RequestBody Article article) { articleService.updateArticle(article); return new ResponseEntity<Article>(article, HttpStatus.OK); } @DeleteMapping("article/{id}") public ResponseEntity<Void> deleteArticle(@PathVariable("id") Integer id) { articleService.deleteArticle(id); return new ResponseEntity<Void>(HttpStatus.NO_CONTENT); } }
8. Spring Data CrudRepository + JPA + Hibernate Example using XML Configuration
Find the project structure of our project using XML configuration.
jpa-config.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:tx="http://www.springframework.org/schema/tx" xmlns:jpa="http://www.springframework.org/schema/data/jpa" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/data/jpa http://www.springframework.org/schema/data/jpa/spring-jpa.xsd"> <context:property-placeholder location="classpath:database.properties"/> <jpa:repositories base-package="com.concretepage.repository" /> <bean id="basicDataSource" class="org.apache.commons.dbcp2.BasicDataSource" destroy-method="close"> <property name="driverClassName" value="${database.driverClassName}" /> <property name="url" value="${database.url}" /> <property name="username" value="${database.username}" /> <property name="password" value="${database.password}" /> </bean> <bean name="hibernateJpaVendorAdapter" class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"/> <bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"> <property name="jpaVendorAdapter" ref="hibernateJpaVendorAdapter" /> <property name="dataSource" ref="basicDataSource" /> <property name="persistenceUnitName" value="myJpaPersistenceUnit" /> <property name="packagesToScan"> <list> <value>com.concretepage.entity</value> </list> </property> <property name="jpaProperties"> <props> <prop key="hibernate.dialect">${hibernate.dialect}</prop> <prop key="hibernate.show_sql">${hibernate.show_sql}</prop> <prop key="hibernate.format_sql">${hibernate.format_sql}</prop> <prop key="hibernate.id.new_generator_mappings">${hibernate.id.new_generator_mappings}</prop> </props> </property> </bean> <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager"> <property name="entityManagerFactory" ref="entityManagerFactory" /> </bean> <tx:annotation-driven transaction-manager="transactionManager" /> </beans>
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context" xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> <context:component-scan base-package="com.concretepage" /> <bean name="jackson2ObjectMapper" class="org.springframework.http.converter.json.Jackson2ObjectMapperFactoryBean"> <property name="indentOutput" value="true"/> </bean> <mvc:annotation-driven> <mvc:message-converters> <bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter"> <property name="objectMapper" ref="jackson2ObjectMapper" /> </bean> </mvc:message-converters> </mvc:annotation-driven> </beans>
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0"> <display-name>Spring Demo Project</display-name> <context-param> <param-name>contextConfigLocation</param-name> <param-value> /WEB-INF/dispatcher-servlet.xml /WEB-INF/jpa-config.xml </param-value> </context-param> <servlet> <servlet-name>dispatcher</servlet-name> <servlet-class> org.springframework.web.servlet.DispatcherServlet </servlet-class> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>dispatcher</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> </web-app>
9. Client Code with RestTemplate to Test CRUD Application
RestClientUtil.javapackage com.concretepage.client; import java.net.URI; import org.springframework.http.HttpEntity; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpMethod; import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; import org.springframework.web.client.RestTemplate; import com.concretepage.entity.Article; public class RestClientUtil { public void getArticleByIdDemo() { HttpHeaders headers = new HttpHeaders(); headers.setContentType(MediaType.APPLICATION_JSON); RestTemplate restTemplate = new RestTemplate(); String url = "http://localhost:8080/spring-app/user/article/{id}"; HttpEntity<String> requestEntity = new HttpEntity<String>(headers); ResponseEntity<Article> responseEntity = restTemplate.exchange(url, HttpMethod.GET, requestEntity, Article.class, 1); Article article = responseEntity.getBody(); System.out.println("Id:"+article.getArticleId()+", Title:"+article.getTitle() +", Category:"+article.getCategory()); } public void getAllArticlesDemo() { HttpHeaders headers = new HttpHeaders(); headers.setContentType(MediaType.APPLICATION_JSON); RestTemplate restTemplate = new RestTemplate(); String url = "http://localhost:8080/spring-app/user/articles"; HttpEntity<String> requestEntity = new HttpEntity<String>(headers); ResponseEntity<Article[]> responseEntity = restTemplate.exchange(url, HttpMethod.GET, requestEntity, Article[].class); Article[] articles = responseEntity.getBody(); for(Article article : articles) { System.out.println("Id:"+article.getArticleId()+", Title:"+article.getTitle() +", Category: "+article.getCategory()); } } public void addArticleDemo() { HttpHeaders headers = new HttpHeaders(); headers.setContentType(MediaType.APPLICATION_JSON); RestTemplate restTemplate = new RestTemplate(); String url = "http://localhost:8080/spring-app/user/article"; Article objArticle = new Article(); objArticle.setTitle("Spring REST Security using Hibernate"); objArticle.setCategory("Spring"); HttpEntity<Article> requestEntity = new HttpEntity<Article>(objArticle, headers); URI uri = restTemplate.postForLocation(url, requestEntity); System.out.println(uri.getPath()); } public void updateArticleDemo() { HttpHeaders headers = new HttpHeaders(); headers.setContentType(MediaType.APPLICATION_JSON); RestTemplate restTemplate = new RestTemplate(); String url = "http://localhost:8080/spring-app/user/article"; Article objArticle = new Article(); objArticle.setArticleId(1); objArticle.setTitle("Update:Java Concurrency"); objArticle.setCategory("Java"); HttpEntity<Article> requestEntity = new HttpEntity<Article>(objArticle, headers); restTemplate.put(url, requestEntity); } public void deleteArticleDemo() { HttpHeaders headers = new HttpHeaders(); headers.setContentType(MediaType.APPLICATION_JSON); RestTemplate restTemplate = new RestTemplate(); String url = "http://localhost:8080/spring-app/user/article/{id}"; HttpEntity<Article> requestEntity = new HttpEntity<Article>(headers); restTemplate.exchange(url, HttpMethod.DELETE, requestEntity, Void.class, 4); } public static void main(String args[]) { RestClientUtil util = new RestClientUtil(); //util.getArticleByIdDemo(); util.addArticleDemo(); //util.updateArticleDemo(); //util.deleteArticleDemo(); util.getAllArticlesDemo(); } }
10. Run and Test Application
To build and run the demo application, follow the steps.1. Import table in MySQL database given above on this page.
2. Download the source code from the link given below on this page.
3. Go to the root directory of the project using command prompt.
4. Build the project using gradle with following command.
gradle clean build
mvn clean package
5. Deploy the WAR file using tomcat.
6. To test the application, use
RestClientUtil.java
file given in the demo project. We can also test application using Postman. Find the print screen.

11. References
Interface CrudRepositorySpring Data JPA - Reference Documentation