diff --git a/build.gradle b/build.gradle index b7867b9..d787b0f 100644 --- a/build.gradle +++ b/build.gradle @@ -7,6 +7,18 @@ plugins { group = 'com.example' version = '0.0.1-SNAPSHOT' +defaultTasks 'bootRun' + +jar { + enabled = false +} + +bootJar { + archiveFileName = String.format('%s-%s.jar', rootProject.name, version) +} + +assert System.properties['java.specification.version'] == '17' || '21' + java { sourceCompatibility = '17' } @@ -17,9 +29,13 @@ repositories { dependencies { implementation 'org.springframework.boot:spring-boot-starter-web' + implementation 'org.springframework.boot:spring-boot-starter-validation' implementation 'org.springdoc:springdoc-openapi-starter-webmvc-ui:2.3.0' implementation 'org.modelmapper:modelmapper:3.2.0' + implementation 'org.springframework.boot:spring-boot-starter-data-jpa' + implementation 'com.h2database:h2:2.2.224' + testImplementation 'org.springframework.boot:spring-boot-starter-test' } diff --git a/src/main/java/com/example/demo/core/configuration/Constants.java b/src/main/java/com/example/demo/core/configuration/Constants.java index b005cdc..7bb609d 100644 --- a/src/main/java/com/example/demo/core/configuration/Constants.java +++ b/src/main/java/com/example/demo/core/configuration/Constants.java @@ -1,6 +1,8 @@ package com.example.demo.core.configuration; public class Constants { + public static final String SEQUENCE_NAME = "hibernate_sequence"; + public static final String API_URL = "/api/1.0"; private Constants() { diff --git a/src/main/java/com/example/demo/core/error/NotFoundException.java b/src/main/java/com/example/demo/core/error/NotFoundException.java index 586af3c..a61d118 100644 --- a/src/main/java/com/example/demo/core/error/NotFoundException.java +++ b/src/main/java/com/example/demo/core/error/NotFoundException.java @@ -1,7 +1,7 @@ package com.example.demo.core.error; public class NotFoundException extends RuntimeException { - public NotFoundException(Long id) { - super(String.format("Entity with id [%s] is not found or not exists", id)); + public NotFoundException(Class clazz, Long id) { + super(String.format("%s with id [%s] is not found or not exists", clazz.getSimpleName(), id)); } } diff --git a/src/main/java/com/example/demo/core/model/BaseEntity.java b/src/main/java/com/example/demo/core/model/BaseEntity.java index e5e12d8..72d46ce 100644 --- a/src/main/java/com/example/demo/core/model/BaseEntity.java +++ b/src/main/java/com/example/demo/core/model/BaseEntity.java @@ -1,15 +1,23 @@ package com.example.demo.core.model; +import com.example.demo.core.configuration.Constants; + +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import jakarta.persistence.MappedSuperclass; +import jakarta.persistence.SequenceGenerator; + +@MappedSuperclass public abstract class BaseEntity { + @Id + @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = Constants.SEQUENCE_NAME) + @SequenceGenerator(name = Constants.SEQUENCE_NAME, sequenceName = Constants.SEQUENCE_NAME, allocationSize = 1) protected Long id; protected BaseEntity() { } - protected BaseEntity(Long id) { - this.id = id; - } - public Long getId() { return id; } diff --git a/src/main/java/com/example/demo/core/repository/CommonRepository.java b/src/main/java/com/example/demo/core/repository/CommonRepository.java deleted file mode 100644 index acf104e..0000000 --- a/src/main/java/com/example/demo/core/repository/CommonRepository.java +++ /dev/null @@ -1,17 +0,0 @@ -package com.example.demo.core.repository; - -import java.util.List; - -public interface CommonRepository { - List getAll(); - - E get(T id); - - E create(E entity); - - E update(E entity); - - E delete(E entity); - - void deleteAll(); -} diff --git a/src/main/java/com/example/demo/core/repository/MapRepository.java b/src/main/java/com/example/demo/core/repository/MapRepository.java deleted file mode 100644 index a38d03d..0000000 --- a/src/main/java/com/example/demo/core/repository/MapRepository.java +++ /dev/null @@ -1,57 +0,0 @@ -package com.example.demo.core.repository; - -import java.util.List; -import java.util.Map; -import java.util.TreeMap; - -import com.example.demo.core.model.BaseEntity; - -public abstract class MapRepository implements CommonRepository { - private final Map entities = new TreeMap<>(); - private Long lastId = 0L; - - protected MapRepository() { - } - - @Override - public List getAll() { - return entities.values().stream().toList(); - } - - @Override - public E get(Long id) { - return entities.get(id); - } - - @Override - public E create(E entity) { - lastId++; - entity.setId(lastId); - entities.put(lastId, entity); - return entity; - } - - @Override - public E update(E entity) { - if (get(entity.getId()) == null) { - return null; - } - entities.put(entity.getId(), entity); - return entity; - } - - @Override - public E delete(E entity) { - if (get(entity.getId()) == null) { - return null; - } - entities.remove(entity.getId()); - return entity; - } - - @Override - public void deleteAll() { - lastId = 0L; - entities.clear(); - } -} diff --git a/src/main/java/com/example/demo/department/model/DepartmentEntity.java b/src/main/java/com/example/demo/department/model/DepartmentEntity.java index d351b8e..a815e67 100644 --- a/src/main/java/com/example/demo/department/model/DepartmentEntity.java +++ b/src/main/java/com/example/demo/department/model/DepartmentEntity.java @@ -4,15 +4,20 @@ import java.util.Objects; import com.example.demo.core.model.BaseEntity; +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.Table; + +@Entity +@Table(name = "departments") public class DepartmentEntity extends BaseEntity { + @Column(nullable = false, unique = true, length = 80) private String name; public DepartmentEntity() { - super(); } public DepartmentEntity(Long id, String name) { - super(id); this.name = name; } diff --git a/src/main/java/com/example/demo/department/repository/DepartmentRepository.java b/src/main/java/com/example/demo/department/repository/DepartmentRepository.java index 59236f3..f9b707b 100644 --- a/src/main/java/com/example/demo/department/repository/DepartmentRepository.java +++ b/src/main/java/com/example/demo/department/repository/DepartmentRepository.java @@ -1,10 +1,11 @@ package com.example.demo.department.repository; -import org.springframework.stereotype.Repository; +import java.util.Optional; + +import org.springframework.data.repository.CrudRepository; -import com.example.demo.core.repository.MapRepository; import com.example.demo.department.model.DepartmentEntity; -@Repository -public class DepartmentRepository extends MapRepository { +public interface DepartmentRepository extends CrudRepository { + Optional findByNameIgnoreCase(String name); } diff --git a/src/main/java/com/example/demo/department/service/DepartmentService.java b/src/main/java/com/example/demo/department/service/DepartmentService.java index b745346..8af28da 100644 --- a/src/main/java/com/example/demo/department/service/DepartmentService.java +++ b/src/main/java/com/example/demo/department/service/DepartmentService.java @@ -1,9 +1,10 @@ package com.example.demo.department.service; import java.util.List; -import java.util.Optional; +import java.util.stream.StreamSupport; import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; import com.example.demo.core.error.NotFoundException; import com.example.demo.department.model.DepartmentEntity; @@ -17,27 +18,45 @@ public class DepartmentService { this.repository = repository; } + private void checkName(String name) { + if (repository.findByNameIgnoreCase(name).isPresent()) { + throw new IllegalArgumentException( + String.format("Type with name %s is already exists", name)); + } + } + + @Transactional(readOnly = true) public List getAll() { - return repository.getAll(); + return StreamSupport.stream(repository.findAll().spliterator(), false).toList(); } + @Transactional(readOnly = true) public DepartmentEntity get(Long id) { - return Optional.ofNullable(repository.get(id)) - .orElseThrow(() -> new NotFoundException(id)); + return repository.findById(id) + .orElseThrow(() -> new NotFoundException(DepartmentEntity.class, id)); } + @Transactional public DepartmentEntity create(DepartmentEntity entity) { - return repository.create(entity); + if (entity == null) { + throw new IllegalArgumentException("Entity is null"); + } + checkName(entity.getName()); + return repository.save(entity); } + @Transactional public DepartmentEntity update(Long id, DepartmentEntity entity) { final DepartmentEntity existsEntity = get(id); + checkName(entity.getName()); existsEntity.setName(entity.getName()); - return repository.update(existsEntity); + return repository.save(existsEntity); } + @Transactional public DepartmentEntity delete(Long id) { final DepartmentEntity existsEntity = get(id); - return repository.delete(existsEntity); + repository.delete(existsEntity); + return existsEntity; } }