In this tutorial I am going to show you an example on deploying Spring Boot application to Heroku cloud. I will create a basic CRUD application with Spring Boot Data JPA and PostgreSQL/MySQL technologies. I will first show you how to perform CRUD operations locally, then deploy the same application in the Heroku cloud with some modifications.
CRUD is an acronym that stands for Create, Read, Update and Delete. I am building REST APIs using Spring Boot framework. I will use Postman tool to access and test the REST web services. I am going to show you how to import your local application code and local PostgreSQL database.
I am not using MySQL database in Heroku cloud for this example. If you need to use MySQL database then you can use command
heroku addons:create cleardb:ignite to install as an add-on but you need to verify your account by using your credit card details. You can refer to the example deploying Python Flask MySQL app to Heroku. When I wrote this Python based app I did not have to use credit card but nowadays Heroku made it mandatory. So I am using here PostgreSQL database which does not need any credit card verification as of now.
Spring Data JPA CRUD
Now I will first create Spring Boot Data JPA PostgreSQL/MySQL CRUD application.
You need to create a maven based project in your favorite tool or IDE. The following pom.xml is given as the project’s build file.
I have declared MySQL and PostgreSQL dependencies and you can decide which one is your requirement.
<?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.roytuts</groupId> <artifactId>spring-data-jpa-mysql-crud</artifactId> <version>0.0.1-SNAPSHOT</version> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <maven.compiler.source>12</maven.compiler.source> <maven.compiler.target>12</maven.compiler.target> </properties> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.4.2</version> </parent> <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> </dependency> --> <dependency> <groupId>org.postgresql</groupId> <artifactId>postgresql</artifactId> </dependency> <dependency> <groupId>javax.xml.bind</groupId> <artifactId>jaxb-api</artifactId> <scope>runtime</scope> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project>
The whole source code can be downloaded from the Git Repository (spring-data-jpa-mysql-crud).
I am not going to show you the whole source code here but you need to download it first before moving down.
I am using MySQL database server for storing data. So here is the structure of the category table under roytuts database.
CREATE TABLE IF NOT EXISTS `category` ( `id` int unsigned NOT NULL AUTO_INCREMENT, `name` varchar(50) NOT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
The similar table has to be created in the PostgreSQL database server if you are using PostgreSQL server.
CREATE TABLE public.category ( id integer NOT NULL, name character varying(50) NOT NULL );
Remember the application will work with both MySQL and PostgreSQL database servers.
Testing the Application
Once the Spring Boot application is run on localhost and port 8080 you can test the REST web services through any REST client. Now I will show you CRUD operations through Postman tool.
The following image shows how to create new category as many as you want.
The below image shows how to fetch all categories from the server side:
Next I am showing you how get a particular by id:
You can also fetch a category by its name:
You can delete a particular category by its id:
Now I am going to tell you how to prepare the local application for deployment on Heroku cloud server.
Initialize Git Repository
Let’s say my Spring Boot application’s root folder is spring-data-jpa-crud.
Navigate to the application’s root directory in the command line tool using command
Now you need to execute the command
git init to initialize the git repository. You will see similar to the below message:
Initialized empty Git repository in <spring boot app path>/spring-data-jpa-crud/.git/
Now you need to add all files into the git repository by executing command
git add . The add tells to add files. The dot(.) means all files.
Then commit the files into git repository using
git commit -m "spring boot data jpa crud", where the command
commit is used to commit and
-m is used to pass a message.
So you will find similar message after executing the commit command:
[master (root-commit) b3d4e12] spring boot data jpa crud 7 files changed, 238 insertions(+) create mode 100644 pom.xml create mode 100644 src/main/java/com/roytuts/spring/data/jpa/crud/SpringDataJpaMySqlApp.java create mode 100644 src/main/java/com/roytuts/spring/data/jpa/crud/entity/Category.java create mode 100644 src/main/java/com/roytuts/spring/data/jpa/crud/repository/CategoryRepository.java create mode 100644 src/main/java/com/roytuts/spring/data/jpa/crud/rest/controller/CategoryRestController.java create mode 100644 src/main/java/com/roytuts/spring/data/jpa/crud/service/CategoryService.java create mode 100644 src/main/resources/application.properties
Create Heroku Remote
You need to deploy your app by pushing its code to a special Heroku-hosted remote that’s associated with your app.
Make sure you are in the project or application’s root directory on command line tool.
You can create application in Heroku either from the web interface or using command line tool.
If you create from web interface then you have to use the existing app name to sync with git repository.
If you create from command line tool without giving any app name then Heroku will create one for you and sync with your git repository. Even you can create app from command line tool by giving app name.
Let’s say you will create app spring-data-jpa-crud in Heroku server from command line. Therefore you need to use command
heroku create spring-data-jpa-crud.
Please make sure you first login to Heroku before you execute the below command.
Once app created successfully you will get the following message:
Creating spring-data-jpa-crud... done https://spring-data-jpa-crud.herokuapp.com/ | https://git.heroku.com/spring-data-jpa-crud.git
heroku create CLI command creates a new empty application on Heroku, along with an associated empty Git repository. Running this command from your app’s root directory, the empty Heroku Git repository is automatically set as a remote for your local repository.
You can use the
git remote command to confirm that a remote named heroku has been set for your app. You will see below output on executing the command
git remote -v:
heroku https://git.heroku.com/spring-data-jpa-crud.git (fetch) heroku https://git.heroku.com/spring-data-jpa-crud.git (push)
If you want to create app without giving name then execute
heroku create. Then you have to execute the command
git remote -v.
If you already have the app name (created earlier using web interface or command line) then you need to execute only the command:
heroku git:remote -a <app name>.
So you have created remote repository in Heroku successfully but code is not yet there. So you need to push your code into remote repository so that Heroku will find it from remote repository when you deploy the app.
Push the code in the master branch of the remote repository by executing the following command. Make sure you are in the project’s root directory in your local system from the command line.
git push heroku master
The above command will detect the Java application as pom.xml file is there and automatically starts to download, build and deploy it.
Now your app has been deployed into the server and you should be able to access using the given URL https://spring-data-jpa-crud.herokuapp.com/.
You can find the app in the Heroku dashboard:
But you will get application error when you try to access the URL (https://spring-data-jpa-crud.herokuapp.com/categories). You can check the log from the command line using command
heroku logs --tail or using the web interface from: click on the app name spring-data-jpa-crud, click on More on top right and click on View logs.
The error you will find is actually is:
Heroku does not have really MySQL server but it has ClearDB which is used to run your MySQL database without any issue. ClearDB is a powerful, high-speed database-as-a-service in the cloud for your MySQL powered applications.
Refer to the example deploying Python Flask MySQL app to Heroku.
Now I will install PostgreSQL as an add-on from the CLI:
heroku addons:create heroku-postgresql
You will see the following output:
! heroku-cli: update available from 6.15.5-1f03166 to 6.99.0-ec9edad Creating heroku-postgresql on spring-data-jpa-crud... free Database has been created and is available ! This database is empty. If upgrading, you can transfer ! data from another database with pg:copy Created postgresql-flexible-39505 as HEROKU_POSTGRESQL_ROSE_URL Use heroku addons:docs heroku-postgresql to view documentation
Now you can list the configuration variables (using command
heroku config) for your app to display the URL needed to connect to the database, DATABASE_URL:
=== spring-data-jpa-crud Config Vars DATABASE_URL: postgres://ilfndedxuwxhxu:email@example.com:5432/d8lhnd1pla9162
You can check the above URL to match the details:
Database Host: ec2-75-101-212-64.compute-1.amazonaws.com Database User: ilfndedxuwxhxu Database Password: 2502f3afe9d437a01d0c662a32dc7bd26e91ddfed5b0dc710aec03ba305c05cf Database: d8lhnd1pla9162
Now change the src/main/resources/appliation.properties file and update the database settings as below:
spring.datasource.driverClassName=org.postgresql.Driver spring.datasource.url=jdbc:postgresql://ec2-75-101-212-64.compute-1.amazonaws.com/d8lhnd1pla9162 spring.datasource.username=ilfndedxuwxhxu spring.datasource.password=2502f3afe9d437a01d0c662a32dc7bd26e91ddfed5b0dc710aec03ba305c05cf
Now commit the changes to the git and finally execute again the command
git push heroku master. Your build will be success and app will be deployed. Still access to your REST API will be failed because category table does not exist. Next step is to import the PostgreSQL file.
Export SQL File
Before you import the .sql or .pgsql file to Heroku PostgreSQL server, you need to take backup or dump from the local PostgreSQL server. And you can take the dump using the following command:
C:\pgsql\bin>pg_dump.exe -U postgres -d roytuts -f <path where dump should be saved>\roytuts_postgresql_heroku.sql
Where -U followe by database username, -d followed by database name, -f followed by SQL file name.
Import SQL File
Now I am going to import the local PostgreSQL database file into the Heroku server using the following command:
C:\pgsql\bin>psql.exe -h ec2-75-101-212-64.compute-1.amazonaws.com -U ilfndedxuwxhxu d8lhnd1pla9162 < <directory path>\roytuts_postgresql_heroku.sql
So I am executing the local psql.exe with arguments -h for host, -p for port (I am using default port, so I did not mention), -U for username followed by database name and the local .pgsql or .sql file.
Once your command gets executed you will see the following output:
Now database dump has been successfully imported into Heroku cloud PostgreSQL server.
Now you need to restart the application. First scale down, then scale up by using the following commands:
heroku ps:scale web=0 heroku ps:scale web=1
The output of the above commands:
You can also find log in web interface console:
Testing the Application
Now access the URL https://spring-data-jpa-crud.herokuapp.com/categories and you will see the REST API gives you the following output. So the /categories REST endpoint lists all categories.
You can fetch single category by its id:
You can also fetch single category by its name:
You can also perform other operations such as creating new category, updating a category or deleting a category. You can use Postman or any REST client tool to test CRUD operations for REST APIs.
Hope you got an idea how to deploy Spring Boot Data JPA application to Heroku cloud server.