diff --git a/.gitignore b/.gitignore
index a1c2a23..a64734d 100644
--- a/.gitignore
+++ b/.gitignore
@@ -21,3 +21,22 @@
# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
hs_err_pid*
+
+HELP.md
+.gradle
+build/
+!gradle/wrapper/gradle-wrapper.jar
+!**/src/main/**/build/
+!**/src/test/**/build/
+
+### IntelliJ IDEA ###
+.idea
+*.iws
+*.iml
+*.ipr
+out/
+!**/src/main/**/out/
+!**/src/test/**/out/
+
+logs/
+*.lst
diff --git a/pom.xml b/pom.xml
index 0a3999d..6ecc67a 100644
--- a/pom.xml
+++ b/pom.xml
@@ -3,6 +3,13 @@
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
4.0.0
+
+ org.springframework.boot
+ spring-boot-starter-parent
+ 2.4.5
+
+
+
com.mastery
simplewebapp
0.0.1-SNAPSHOT
@@ -11,6 +18,82 @@
demo
Practical task
+
+ 1.9
+ 1.9
+ 1.4.2.Final
+ 1.18.16
+
+
+
+ org.springframework.boot
+ spring-boot-starter-web
+
+
+ org.springframework.boot
+ spring-boot-starter-test
+ test
+
+
+ org.springframework.boot
+ spring-boot-starter-jdbc
+
+
+ org.mapstruct
+ mapstruct
+ 1.4.2.Final
+
+
+ org.mapstruct
+ mapstruct-processor
+ ${mapstruct.version}
+
+
+ org.hibernate.validator
+ hibernate-validator
+ 6.2.0.Final
+
+
+ com.h2database
+ h2
+ 1.4.200
+
+
+ org.projectlombok
+ lombok
+ ${lombok.version}
+
+
+ org.postgresql
+ postgresql
+ 42.2.20
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+ 3.8.1
+
+ 1.9
+ 1.9
+
+
+ org.projectlombok
+ lombok
+ ${lombok.version}
+
+
+ org.mapstruct
+ mapstruct-processor
+ ${mapstruct.version}
+
+
+
+
+
+
diff --git a/src/main/java/com/mastery/java/task/Application.java b/src/main/java/com/mastery/java/task/Application.java
new file mode 100644
index 0000000..04b7089
--- /dev/null
+++ b/src/main/java/com/mastery/java/task/Application.java
@@ -0,0 +1,12 @@
+package com.mastery.java.task;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+@SpringBootApplication
+public class Application {
+
+ public static void main(String[] args) {
+ SpringApplication.run(Application.class, args);
+ }
+}
diff --git a/src/main/java/com/mastery/java/task/config/AppConfiguration.java b/src/main/java/com/mastery/java/task/config/AppConfiguration.java
deleted file mode 100644
index 159a276..0000000
--- a/src/main/java/com/mastery/java/task/config/AppConfiguration.java
+++ /dev/null
@@ -1,4 +0,0 @@
-package com.mastery.java.task.config;
-
-public class AppConfiguration {
-}
diff --git a/src/main/java/com/mastery/java/task/dao/EmployeeDao.java b/src/main/java/com/mastery/java/task/dao/EmployeeDao.java
index edac5b1..00668c4 100644
--- a/src/main/java/com/mastery/java/task/dao/EmployeeDao.java
+++ b/src/main/java/com/mastery/java/task/dao/EmployeeDao.java
@@ -1,4 +1,19 @@
package com.mastery.java.task.dao;
-public class EmployeeDao {
+import com.mastery.java.task.model.Employee;
+
+import java.util.List;
+import java.util.Optional;
+
+public interface EmployeeDao {
+
+ Employee create(Employee employee);
+
+ List findAll();
+
+ Optional findById(long id);
+
+ Employee update(long id, Employee employee);
+
+ void delete(long id);
}
diff --git a/src/main/java/com/mastery/java/task/dao/impl/EmployeeDaoImpl.java b/src/main/java/com/mastery/java/task/dao/impl/EmployeeDaoImpl.java
new file mode 100644
index 0000000..ab1e262
--- /dev/null
+++ b/src/main/java/com/mastery/java/task/dao/impl/EmployeeDaoImpl.java
@@ -0,0 +1,79 @@
+package com.mastery.java.task.dao.impl;
+
+import com.mastery.java.task.dao.EmployeeDao;
+import com.mastery.java.task.mapper.row_mapper.EmployeeRowMapper;
+import com.mastery.java.task.model.Employee;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.jdbc.core.JdbcTemplate;
+import org.springframework.jdbc.core.simple.SimpleJdbcInsert;
+import org.springframework.stereotype.Repository;
+
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+
+@Repository
+public class EmployeeDaoImpl implements EmployeeDao {
+
+ private final JdbcTemplate jdbcTemplate;
+ private SimpleJdbcInsert jdbcInsert;
+
+ @Autowired
+ public EmployeeDaoImpl(JdbcTemplate jdbcTemplate) {
+ this.jdbcTemplate = jdbcTemplate;
+ this.jdbcInsert = new SimpleJdbcInsert(jdbcTemplate)
+ .withSchemaName("employeedb.public")
+ .withTableName("\"‘employee’ \"")
+ .usingColumns("first_name", "last_name", "department_id",
+ "job_title", "gender_id", "date_of_birth")
+ .usingGeneratedKeyColumns("employee_id");
+ ;
+ }
+
+ @Override
+ public Employee create(Employee employee) {
+ Number employeeId = jdbcInsert.executeAndReturnKey(
+ Map.of("first_name", employee.getFirstName(),
+ "last_name", employee.getLastName(),
+ "department_id", employee.getDepartmentId(),
+ "job_title", employee.getJobTitle(),
+ "gender_id", employee.getGender().getId(),
+ "date_of_birth", employee.getDateOfBirth())
+ );
+
+ return employee.setId(employeeId.longValue());
+ }
+
+ @Override
+ public List findAll() {
+ return jdbcTemplate.query(
+ "select employee_id, first_name, last_name, department_id, job_title, gender_id, date_of_birth " +
+ "from public.\"‘employee’ \"",
+ new EmployeeRowMapper());
+ }
+
+ @Override
+ public Optional findById(long id) {
+ return jdbcTemplate.query
+ ("select employee_id, first_name, last_name, department_id, job_title, gender_id, date_of_birth " +
+ "from public.\"‘employee’ \" where employee_id = ?",
+ new Object[]{id}, new EmployeeRowMapper())
+ .stream().findAny();
+ }
+
+ @Override
+ public Employee update(long id, Employee employee) {
+ jdbcTemplate.update(
+ "update public.\"‘employee’ \" set first_name = ?, last_name = ?, department_id = ?, job_title = ?, gender_id = ?, date_of_birth = ? " +
+ "where employee_id = ?",
+ employee.getFirstName(), employee.getLastName(), employee.getDepartmentId(),
+ employee.getJobTitle(), employee.getGender().getId(), employee.getDateOfBirth(), id);
+
+ return employee.setId(id);
+ }
+
+ @Override
+ public void delete(long id) {
+ jdbcTemplate.update("delete from public.\"‘employee’ \" where employee_id = ?", id);
+ }
+}
diff --git a/src/main/java/com/mastery/java/task/dto/Employee.java b/src/main/java/com/mastery/java/task/dto/Employee.java
deleted file mode 100644
index d79d397..0000000
--- a/src/main/java/com/mastery/java/task/dto/Employee.java
+++ /dev/null
@@ -1,7 +0,0 @@
-package com.mastery.java.task.dto;
-
-public class Employee {
- private Long employeeId;
- private String firstName;
- private Gender gender;
-}
diff --git a/src/main/java/com/mastery/java/task/dto/EmployeeDto.java b/src/main/java/com/mastery/java/task/dto/EmployeeDto.java
new file mode 100644
index 0000000..aae6895
--- /dev/null
+++ b/src/main/java/com/mastery/java/task/dto/EmployeeDto.java
@@ -0,0 +1,38 @@
+package com.mastery.java.task.dto;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import javax.validation.constraints.Min;
+import javax.validation.constraints.NotEmpty;
+import javax.validation.constraints.NotNull;
+import java.time.LocalDateTime;
+
+@Data
+@AllArgsConstructor
+@NoArgsConstructor
+public class EmployeeDto {
+
+ private Long employeeId;
+
+ @NotEmpty(message = "First name cannot be empty")
+ private String firstName;
+
+ @NotEmpty(message = "First name cannot be empty")
+ private String lastName;
+
+ @Min(value = 0, message = "Department id has to be greater than 0")
+ @NotNull(message= "Department id cannot be empty")
+ private Long departmentId;
+
+ @NotEmpty(message = "Job title cannot be empty")
+ private String jobTitle;
+
+ @NotEmpty(message = "Gender cannot be empty")
+ private String gender;
+
+ @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd'T'HH:mm:ss")
+ private LocalDateTime dateOfBirth;
+}
diff --git a/src/main/java/com/mastery/java/task/dto/Gender.java b/src/main/java/com/mastery/java/task/dto/Gender.java
deleted file mode 100644
index 37cd1bf..0000000
--- a/src/main/java/com/mastery/java/task/dto/Gender.java
+++ /dev/null
@@ -1,6 +0,0 @@
-package com.mastery.java.task.dto;
-
-public enum Gender {
- MALE,
- FEMALE
-}
diff --git a/src/main/java/com/mastery/java/task/error_handler/ApiError.java b/src/main/java/com/mastery/java/task/error_handler/ApiError.java
new file mode 100644
index 0000000..37c46ca
--- /dev/null
+++ b/src/main/java/com/mastery/java/task/error_handler/ApiError.java
@@ -0,0 +1,27 @@
+package com.mastery.java.task.error_handler;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+import lombok.Setter;
+import org.springframework.http.HttpStatus;
+
+import java.util.Collections;
+import java.util.List;
+
+@Getter
+@Setter
+@AllArgsConstructor
+public class ApiError {
+
+ private HttpStatus status;
+ private String error;
+ private List errors;
+
+ public ApiError(HttpStatus status,
+ String error,
+ String errorAsList) {
+ this.status = status;
+ this.error = error;
+ this.errors = Collections.singletonList(errorAsList);
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/com/mastery/java/task/error_handler/RestResponseEntityExceptionHandler.java b/src/main/java/com/mastery/java/task/error_handler/RestResponseEntityExceptionHandler.java
new file mode 100644
index 0000000..cc2df66
--- /dev/null
+++ b/src/main/java/com/mastery/java/task/error_handler/RestResponseEntityExceptionHandler.java
@@ -0,0 +1,269 @@
+package com.mastery.java.task.error_handler;
+
+import com.mastery.java.task.exeption.EmployeeNotFoundException;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.TypeMismatchException;
+import org.springframework.dao.DataAccessException;
+import org.springframework.dao.DataIntegrityViolationException;
+import org.springframework.http.HttpHeaders;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.MediaType;
+import org.springframework.http.ResponseEntity;
+import org.springframework.http.converter.HttpMessageNotReadableException;
+import org.springframework.validation.FieldError;
+import org.springframework.validation.ObjectError;
+import org.springframework.web.HttpMediaTypeNotAcceptableException;
+import org.springframework.web.HttpMediaTypeNotSupportedException;
+import org.springframework.web.HttpRequestMethodNotSupportedException;
+import org.springframework.web.bind.MethodArgumentNotValidException;
+import org.springframework.web.bind.annotation.ExceptionHandler;
+import org.springframework.web.bind.annotation.RestControllerAdvice;
+import org.springframework.web.context.request.WebRequest;
+import org.springframework.web.method.annotation.MethodArgumentTypeMismatchException;
+import org.springframework.web.servlet.NoHandlerFoundException;
+import org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler;
+
+import javax.validation.ConstraintViolation;
+import javax.validation.ConstraintViolationException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+@Slf4j
+@RestControllerAdvice
+public class RestResponseEntityExceptionHandler extends ResponseEntityExceptionHandler {
+
+
+ @ExceptionHandler(EmployeeNotFoundException.class)
+ public ResponseEntity