Skip to content

Latest commit

 

History

History
300 lines (269 loc) · 7.76 KB

README.md

File metadata and controls

300 lines (269 loc) · 7.76 KB

webservice-springboot2-java11

My web services project with Spring Boot and JPA / Hibernate

Goals

  1. Create Spring Boot Java project
  2. Implement domain model
  3. Structure logical layers: resource, service, repository
  4. Configure test database (H2)
  5. Populate the database
  6. CRUD - Create, Retrieve, Update, Delete
  7. Exception handling

Screenshot_1

Screenshot_2

Screenshot_3

Screenshot_4

Project created

  • Checklist:
  • File -> New -> Spring Starter Project
  1. Maven
  2. Java 11
  3. Packing JAR
  4. Dependencies: Spring Web Starter

User entity and resource

  • Basic entity checklist:
  • Basic attributes
  • Associations (instantiate collections)
  • Constructors
  • Getters & Setters (collections: only get)
  • hashCode & equals
  • Serializable

H2 database, test profile, JPA

  • Checklist:
  • JPA & H2 dependencies
  • application.properties
  • application-test.properties
  • Entity: JPA mapping
  • Dependencies:
<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
	<groupId>com.h2database</groupId>
	<artifactId>h2</artifactId>
	<scope>runtime</scope>
</dependency>
  • application.properties:
spring.profiles.active=test
spring.jpa.open-in-view=true
  • application-test.properties:
spring.datasource.url=jdbc:h2:mem:testdb
spring.datasource.username=sa
spring.datasource.password=
spring.h2.console.enabled=true
spring.h2.console.path=/h2-console
spring.jpa.show-sql=true
spring.jpa.properties.hibernate.format_sql=true

JPA repository, dependency injection, database seeding

  • Checklist:
  • UserRepository extends JPARepository<User, Long>
  • Configuration class for "test" profile
  • @Autowired UserRepository
  • Instantiate objects in memory
  • Persist objects
  • Objects:
User u1 = new User(null, "Maria Brown", "[email protected]", "988888888", "123456");
User u2 = new User(null, "Alex Green", "[email protected]", "977777777", "123456");

Service layer, component registration

Order, Instant, ISO 8601

  • Basic new entity checklist:
  • Entity
  1. "To many" association, lazy loading, JsonIgnore
  • Repository
  • Seed
  • Service
  • Resource
  • Objects:
Order o1 = new Order(null, Instant.parse("2019-06-20T19:53:07Z"), u1);
Order o2 = new Order(null, Instant.parse("2019-07-21T03:42:10Z"), u2);
Order o3 = new Order(null, Instant.parse("2019-07-22T15:21:22Z"), u1);

OrderStatus enum

Category

  • Objects:
Product p1 = new Product(null, "The Lord of the Rings", "Lorem ipsum dolor sit amet, consectetur.", 90.5, "");
Product p2 = new Product(null, "Smart TV", "Nulla eu imperdiet purus. Maecenas ante.", 2190.0, "");
Product p3 = new Product(null, "Macbook Pro", "Nam eleifend maximus tortor, at mollis.", 1250.0, "");
Product p4 = new Product(null, "PC Gamer", "Donec aliquet odio ac rhoncus cursus.", 1200.0, "");
Product p5 = new Product(null, "Rails for Dummies", "Cras fringilla convallis sem vel faucibus.", 100.99, "");

Many-to-many association with JoinTable

  • in commits

OrderItem, many-to-many association with extra attributes

  • Checklist:
  • OrderItemPK
  • OrderItem
  • Order one-to-many association
  • Seed
  • Objects:
OrderItem oi1 = new OrderItem(o1, p1, 2, p1.getPrice());
OrderItem oi2 = new OrderItem(o1, p3, 1, p3.getPrice());
OrderItem oi3 = new OrderItem(o2, p3, 2, p3.getPrice());
OrderItem oi4 = new OrderItem(o3, p5, 2, p5.getPrice());

Product-OrderItem one-to-many association

  • in commits

Payment, one-to-one association

  • in commits

Subtotal & Total methods

  • in commits

User insert

  • Checklist:
  • UserService
  • UserResource
  • Test:
{
	"name": "Bob Brown",
	"email": "[email protected]",
	"phone": "977557755",
	"password": "123456"
}

User delete

  • Checklist:
  • UserService
  • UserResource

User update

  • Checklist:
  • UserService
  • UserResource
  • Test:
{
	"name": "Bob Brown",
	"email": "[email protected]",
	"phone": "977557755"
}

Exception handling - findById

  • Checklist:
  • NEW CLASS: services.exceptions.ResourceNotFoundException
  • NEW CLASS: resources.exceptions.StandardError
  • NEW CLASS: resources.exceptions.ResourceExceptionHandler
  • UserService

Exception handling - delete

  • Checklist:
  • NEW CLASS: services.exceptions.DatabaseException
  • ResourceExceptionHandler
  • UserService
  1. EmptyResultDataAccessException
  2. DataIntegrityViolationException

Exception handling - update

  • Checklist:
  • UserService
  1. EntityNotFoundException

Create Heroku app & provision PostgreSQL

  • Checklist:
  • Heroku Sign Up
  • Create app
  • Provision PostgreSQL
  1. App dashboard -> Resources
  2. Search "postgres" -> select "Heroku Postgres"

Install local PostgreSQL

  1. Super user: postgres
  2. Password: 1234567
  3. Port: 5432
  • Start/stop service: Task manager -> Services
  • Check instalation
  1. Start pgAdmin
  2. Databases -> Create -> Database
  • Encoding: UTF8

Dev profile

  • Checklist:
  • PgAdmin: create local database: create database springboot
  • Add PostgreSQL Maven dependency
<dependency>
	<groupId>org.postgresql</groupId>
	<artifactId>postgresql</artifactId>
	<scope>runtime</scope>
</dependency>
  • Create file: application-dev.properties
spring.datasource.url=jdbc:postgresql://localhost:5432/springboot
spring.datasource.username=postgres
spring.datasource.password=1234567

spring.jpa.properties.hibernate.jdbc.lob.non_contextual_creation=true
spring.jpa.hibernate.ddl-auto=update
spring.jpa.show-sql=true
spring.jpa.properties.hibernate.format_sql=true

jwt.secret=MYJWTSECRET
jwt.expiration=3600000
  • Update application.properties: spring.profiles.active=dev
  • Run application

Get SQL script from local PostgreSQL

  • PgAdmin: get SQL script:
  1. Select database
  2. Tools -> Backup
  • Format: Plain
  • Encoding: UTF8
  • Dump options:
  • Only schema: YES
  • Blobs: NO
  • Do not save: (ALL)
  • Verbose messages: NO
  • Delete instructions before CREATE statements

Run SQL Script

  • Checklist:
  • App dashboard -> Settings - > Config Vars
  • EXAMPLE:
postgres://wavglvupbdad:358f443aafe452eca4c58fbc15d02e50b08130c7aaea3aff6c4f59c
[email protected]:5432/d7u9ub86cdsu
user: wavglvupbdad
password: 358f443aafe452eca4c58fbc15d02e50b08130c7aaea3aff6c4f59c13f9abb
server: ec2-23-21-106-266.compute-1.amazonaws.com
port: 5432
database: d7u9ub86cdsu
  • PgAdmin: Servers -> Create -> Server
  1. Advanced -> DB rescriction: (database)
  • Database -> Query Tool
  1. Load and run SQL Script

Deploy app to Heroku

  • Heroku app dashboard -> Deploy
heroku git:remote -a myapp
git remote -v
  • Setup Heroku app Config Vars
  1. DATABASE_URL
  2. JWT_EXPIRATION
  3. JWT_SECRET
  • Create: application-prod.properties
spring.datasource.url=${DATABASE_URL}

spring.jpa.hibernate.ddl-auto=none
spring.jpa.show-sql=false
spring.jpa.properties.hibernate.format_sql=false

jwt.secret=${JWT_SECRET}
jwt.expiration=${JWT_EXPIRATION}

Update application.properties: spring.profiles.active=prod

  • Create files: system.properties
  1. java.runtime.version=11
  • Send to Heroku:
  1. git add .
  2. git commit -m "Deploy app to Heroku"
  3. git push heroku master