Posted on: January 19, 2025 Posted by: rahulgite Comments: 0
// Step 1: Create a Spring Boot Application

// File: Application.java
@SpringBootApplication
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

// Step 2: Create an Entity

// File: Employee.java
@Entity
@Table(name = "employees")
public class Employee {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @Column(nullable = false)
    private String name;

    @Column(nullable = false)
    private String department;

    @Column(nullable = false)
    private double salary;

    @OneToOne(mappedBy = "employee", cascade = CascadeType.ALL)
    private Address address;

    @OneToMany(mappedBy = "employee", cascade = CascadeType.ALL)
    private List<Project> projects;

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "manager_id")
    private Employee manager;

    @ManyToMany
    @JoinTable(
        name = "employee_roles",
        joinColumns = @JoinColumn(name = "employee_id"),
        inverseJoinColumns = @JoinColumn(name = "role_id")
    )
    private Set<Role> roles;

    // Getters and setters
}

// File: Address.java
@Entity
@Table(name = "addresses")
public class Address {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @Column(nullable = false)
    private String street;

    @Column(nullable = false)
    private String city;

    @Column(nullable = false)
    private String zipCode;

    @OneToOne
    @JoinColumn(name = "employee_id")
    private Employee employee;

    // Getters and setters
}

// File: Project.java
@Entity
@Table(name = "projects")
public class Project {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @Column(nullable = false)
    private String name;

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "employee_id")
    private Employee employee;

    // Getters and setters
}

// File: Role.java
@Entity
@Table(name = "roles")
public class Role {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @Column(nullable = false, unique = true)
    private String name;

    @ManyToMany(mappedBy = "roles")
    private Set<Employee> employees;

    // Getters and setters
}

// Step 3: Create a Repository

// File: EmployeeRepository.java
@Repository
public interface EmployeeRepository extends JpaRepository<Employee, Long> {

    // Derived query methods
    List<Employee> findByDepartment(String department);

    // Custom JPQL query
    @Query("SELECT e FROM Employee e WHERE e.salary > :salary")
    List<Employee> findEmployeesWithSalaryGreaterThan(@Param("salary") double salary);

    // Native SQL query
    @Query(value = "SELECT * FROM employees WHERE name LIKE %:name%", nativeQuery = true)
    List<Employee> searchByName(@Param("name") String name);

    // Transactional example
    @Modifying
    @Transactional
    @Query("UPDATE Employee e SET e.salary = :salary WHERE e.id = :id")
    int updateSalary(@Param("id") Long id, @Param("salary") double salary);
}

// File: AddressRepository.java
@Repository
public interface AddressRepository extends JpaRepository<Address, Long> {}

// File: ProjectRepository.java
@Repository
public interface ProjectRepository extends JpaRepository<Project, Long> {}

// File: RoleRepository.java
@Repository
public interface RoleRepository extends JpaRepository<Role, Long> {}

// Step 4: Create a Service

// File: EmployeeService.java
@Service
@Transactional
public class EmployeeService {

    private final EmployeeRepository repository;

    public EmployeeService(EmployeeRepository repository) {
        this.repository = repository;
    }

    public List<Employee> getAllEmployees() {
        return repository.findAll();
    }

    public Employee getEmployeeById(Long id) {
        return repository.findById(id).orElseThrow(() -> new EntityNotFoundException("Employee not found"));
    }

    public Employee createEmployee(Employee employee) {
        return repository.save(employee);
    }

    public Employee updateEmployee(Long id, Employee employeeDetails) {
        Employee employee = getEmployeeById(id);
        employee.setName(employeeDetails.getName());
        employee.setDepartment(employeeDetails.getDepartment());
        employee.setSalary(employeeDetails.getSalary());
        return repository.save(employee);
    }

    public void deleteEmployee(Long id) {
        if (!repository.existsById(id)) {
            throw new EntityNotFoundException("Employee not found");
        }
        repository.deleteById(id);
    }

    public List<Employee> getByDepartment(String department) {
        return repository.findByDepartment(department);
    }

    public List<Employee> findEmployeesWithSalaryGreaterThan(double salary) {
        return repository.findEmployeesWithSalaryGreaterThan(salary);
    }

    public List<Employee> searchByName(String name) {
        return repository.searchByName(name);
    }

    public int updateSalary(Long id, double salary) {
        return repository.updateSalary(id, salary);
    }
}

// Step 5: Create a Controller

// File: EmployeeController.java
@RestController
@RequestMapping("/api/employees")
public class EmployeeController {

    private final EmployeeService service;

    public EmployeeController(EmployeeService service) {
        this.service = service;
    }

    // Create a new employee
    @PostMapping
    public ResponseEntity<Employee> createEmployee(@RequestBody Employee employee) {
        return ResponseEntity.status(HttpStatus.CREATED).body(service.createEmployee(employee));
    }

    // Get all employees
    @GetMapping
    public List<Employee> getAllEmployees() {
        return service.getAllEmployees();
    }

    // Get employee by ID
    @GetMapping("/{id}")
    public ResponseEntity<Employee> getEmployeeById(@PathVariable Long id) {
        return ResponseEntity.ok(service.getEmployeeById(id));
    }

    // Update an employee
    @PutMapping("/{id}")
    public ResponseEntity<Employee> updateEmployee(@PathVariable Long id, @RequestBody Employee employeeDetails) {
        return ResponseEntity.ok(service.updateEmployee(id, employeeDetails));
    }

    // Delete an employee
    @DeleteMapping("/{id}")
    public ResponseEntity<Void> deleteEmployee(@PathVariable Long id) {
        service.deleteEmployee(id);
        return ResponseEntity.noContent().build();
    }

    // Find employees by department
    @GetMapping("/department")
    public List<Employee> getByDepartment(@RequestParam String department) {
        return service.getByDepartment(department);
    }

    // Find employees with salary greater than
    @GetMapping("/salary")
    public List<Employee> getBySalary(@RequestParam double salary) {
        return service.findEmployeesWithSalaryGreaterThan(salary);
    }

    // Search by name
    @GetMapping("/search")
    public List<Employee> searchByName(@RequestParam String name) {
        return service.searchByName(name);
    }

    // Update salary
    @PatchMapping("/{id}/salary")
    public ResponseEntity<String> updateSalary(@PathVariable Long id, @RequestParam double salary) {
        int updated = service.updateSalary(id, salary);
        return updated > 0 ? ResponseEntity.ok("Salary updated successfully") : ResponseEntity.status(HttpStatus.NOT_MODIFIED).body("Update failed");
    }
}

// Step 6: Exception Handling

// File: GlobalExceptionHandler.java
@RestControllerAdvice
public class GlobalExceptionHandler {

    @ExceptionHandler(EntityNotFoundException.class)
    public ResponseEntity<String> handleEntityNotFound(EntityNotFoundException ex) {
        return ResponseEntity.status(HttpStatus.NOT_FOUND).body(ex.getMessage());
    }

    @ExceptionHandler(Exception.class)
    public ResponseEntity<String> handleGeneralException(Exception ex) {
        return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("An unexpected error occurred: " + ex.getMessage());
    }
}

// File: Custom Exceptions
public class EntityNotFoundException extends RuntimeException {
    public EntityNotFoundException(String message) {
        super(message);
    }
}

// Step 7: Configure In-Memory Database

// File: application.properties
spring.datasource.url=jdbc:h2:mem:testdb
spring.datasource.driverClassName=org.h2.Driver
spring.datasource.username=sa
spring.datasource.password=password
spring.jpa.database-platform=org.hibernate.dialect.H2Dialect
spring.h2.console.enabled=true

Leave a Comment