From 4dbd7257801fd74bfdf13e500a302719be9cae04 Mon Sep 17 00:00:00 2001 From: Zakharov_Rostislav Date: Thu, 11 Apr 2024 13:37:30 +0400 Subject: [PATCH 01/21] lab-3 in process --- SpringApp/library/build.gradle | 17 +++++- .../com/ip/library/authors/api/AuthorDto.java | 4 +- .../library/authors/model/AuthorEntity.java | 10 +++- .../authors/repository/AuthorRepository.java | 9 +-- .../authors/service/AuthorService.java | 36 ++++++++++-- .../ip/library/books/model/BookEntity.java | 17 +++++- .../books/repository/BookRepository.java | 13 +++-- .../ip/library/books/service/BookService.java | 26 +++++---- .../library/core/configuration/Constants.java | 2 + .../library/core/error/NotFoundException.java | 4 +- .../com/ip/library/core/model/BaseEntity.java | 16 ++++-- .../core/repository/CommonRepository.java | 17 ------ .../core/repository/MapRepository.java | 57 ------------------- .../com/ip/library/types/api/TypeDto.java | 6 +- .../ip/library/types/model/TypeEntity.java | 10 +++- .../types/repository/TypeRepository.java | 9 +-- .../ip/library/types/service/TypeService.java | 39 ++++++++++--- .../ip/library/users/model/UserEntity.java | 28 +++++---- .../ip/library/users/service/UserService.java | 2 +- .../test/java/com/ip/library/UsersTests.java | 8 +-- 20 files changed, 188 insertions(+), 142 deletions(-) delete mode 100644 SpringApp/library/src/main/java/com/ip/library/core/repository/CommonRepository.java delete mode 100644 SpringApp/library/src/main/java/com/ip/library/core/repository/MapRepository.java diff --git a/SpringApp/library/build.gradle b/SpringApp/library/build.gradle index cd71bb9..6cb9492 100644 --- a/SpringApp/library/build.gradle +++ b/SpringApp/library/build.gradle @@ -7,6 +7,17 @@ plugins { group = 'com.ip' 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,10 +28,12 @@ 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' - - developmentOnly 'org.springframework.boot:spring-boot-devtools' + + 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/SpringApp/library/src/main/java/com/ip/library/authors/api/AuthorDto.java b/SpringApp/library/src/main/java/com/ip/library/authors/api/AuthorDto.java index 4601838..59fb8c3 100644 --- a/SpringApp/library/src/main/java/com/ip/library/authors/api/AuthorDto.java +++ b/SpringApp/library/src/main/java/com/ip/library/authors/api/AuthorDto.java @@ -3,13 +3,15 @@ package com.ip.library.authors.api; import com.fasterxml.jackson.annotation.JsonProperty; import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.Size; public class AuthorDto { + @JsonProperty(access = JsonProperty.Access.READ_ONLY) private Long id; @NotBlank + @Size(min = 5, max = 20) private String name; - @JsonProperty(access = JsonProperty.Access.READ_ONLY) public Long getId() { return id; } diff --git a/SpringApp/library/src/main/java/com/ip/library/authors/model/AuthorEntity.java b/SpringApp/library/src/main/java/com/ip/library/authors/model/AuthorEntity.java index 9f6df0a..2420b69 100644 --- a/SpringApp/library/src/main/java/com/ip/library/authors/model/AuthorEntity.java +++ b/SpringApp/library/src/main/java/com/ip/library/authors/model/AuthorEntity.java @@ -4,15 +4,21 @@ import java.util.Objects; import com.ip.library.core.model.BaseEntity; +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.Table; + +@Entity +@Table(name = "authors") public class AuthorEntity extends BaseEntity { + @Column(nullable = false, unique = true, length = 20) private String name; public AuthorEntity() { super(); } - public AuthorEntity(Long id, String name) { - super(id); + public AuthorEntity(String name) { this.name = name; } diff --git a/SpringApp/library/src/main/java/com/ip/library/authors/repository/AuthorRepository.java b/SpringApp/library/src/main/java/com/ip/library/authors/repository/AuthorRepository.java index f8c04fd..0e8e9b6 100644 --- a/SpringApp/library/src/main/java/com/ip/library/authors/repository/AuthorRepository.java +++ b/SpringApp/library/src/main/java/com/ip/library/authors/repository/AuthorRepository.java @@ -1,10 +1,11 @@ package com.ip.library.authors.repository; -import org.springframework.stereotype.Repository; +import java.util.Optional; + +import org.springframework.data.repository.CrudRepository; import com.ip.library.authors.model.AuthorEntity; -import com.ip.library.core.repository.MapRepository; -@Repository -public class AuthorRepository extends MapRepository { +public interface AuthorRepository extends CrudRepository { + Optional findByNameIgnoreCase(String name); } diff --git a/SpringApp/library/src/main/java/com/ip/library/authors/service/AuthorService.java b/SpringApp/library/src/main/java/com/ip/library/authors/service/AuthorService.java index cc616d3..800ff31 100644 --- a/SpringApp/library/src/main/java/com/ip/library/authors/service/AuthorService.java +++ b/SpringApp/library/src/main/java/com/ip/library/authors/service/AuthorService.java @@ -2,8 +2,10 @@ package com.ip.library.authors.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.ip.library.core.error.NotFoundException; import com.ip.library.authors.model.AuthorEntity; @@ -17,27 +19,49 @@ public class AuthorService { this.repository = repository; } + private void checkNameUniqueness(String name) { + if (repository.findByNameIgnoreCase(name).isPresent()) { + throw new IllegalArgumentException( + String.format("Author with name %s already exists", name) + ); + } + } + + @Transactional(readOnly = true) public List getAll() { - return repository.getAll(); + return StreamSupport.stream(repository.findAll().spliterator(), false).toList(); } + @Transactional(readOnly = true) public AuthorEntity get(Long id) { - return Optional.ofNullable(repository.get(id)) - .orElseThrow(() -> new NotFoundException(id)); + return repository.findById(id) + .orElseThrow(() -> new NotFoundException(AuthorEntity.class, id)); } + @Transactional public AuthorEntity create(AuthorEntity entity) { - return repository.create(entity); + if (entity == null) { + throw new IllegalArgumentException("Creating AuthorEntity is null"); + } + checkNameUniqueness(entity.getName()); + return repository.save(entity); } + @Transactional public AuthorEntity update(Long id, AuthorEntity entity) { + if (entity == null) { + throw new IllegalArgumentException("Updating AuthorEntity is null"); + } final AuthorEntity existsEntity = get(id); + checkNameUniqueness(entity.getName()); existsEntity.setName(entity.getName()); - return repository.update(existsEntity); + return repository.save(existsEntity); } + @Transactional public AuthorEntity delete(Long id) { final AuthorEntity existsEntity = get(id); - return repository.delete(existsEntity); + repository.delete(existsEntity); + return existsEntity; } } diff --git a/SpringApp/library/src/main/java/com/ip/library/books/model/BookEntity.java b/SpringApp/library/src/main/java/com/ip/library/books/model/BookEntity.java index e208a76..85831e7 100644 --- a/SpringApp/library/src/main/java/com/ip/library/books/model/BookEntity.java +++ b/SpringApp/library/src/main/java/com/ip/library/books/model/BookEntity.java @@ -4,19 +4,32 @@ import java.util.Objects; import com.ip.library.core.model.BaseEntity; import com.ip.library.types.model.TypeEntity; + +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.JoinColumn; +import jakarta.persistence.ManyToOne; +import jakarta.persistence.Table; + import com.ip.library.authors.model.AuthorEntity; +@Entity +@Table(name = "books") public class BookEntity extends BaseEntity { + @Column(nullable = false, unique = true, length = 50) private String name; + @ManyToOne + @JoinColumn(name = "typeId", nullable = false) private TypeEntity type; + @ManyToOne + @JoinColumn(name = "authorId", nullable = false) private AuthorEntity author; public BookEntity() { super(); } - public BookEntity(Long id, String name, TypeEntity type, AuthorEntity author) { - super(id); + public BookEntity(String name, TypeEntity type, AuthorEntity author) { this.name = name; this.type = type; this.author = author; diff --git a/SpringApp/library/src/main/java/com/ip/library/books/repository/BookRepository.java b/SpringApp/library/src/main/java/com/ip/library/books/repository/BookRepository.java index 55e82c7..ef63859 100644 --- a/SpringApp/library/src/main/java/com/ip/library/books/repository/BookRepository.java +++ b/SpringApp/library/src/main/java/com/ip/library/books/repository/BookRepository.java @@ -1,10 +1,15 @@ package com.ip.library.books.repository; -import org.springframework.stereotype.Repository; +import java.util.List; +import java.util.Optional; + +import org.springframework.data.repository.CrudRepository; import com.ip.library.books.model.BookEntity; -import com.ip.library.core.repository.MapRepository; -@Repository -public class BookRepository extends MapRepository { +public interface BookRepository extends CrudRepository { + Optional findByNameIgnoreCase(String name); + List findByTypeId(long typeId); + List findByAuthorId(long authorId); + List findByTypeIdAndAuthorId(long typeId, long authorId); } diff --git a/SpringApp/library/src/main/java/com/ip/library/books/service/BookService.java b/SpringApp/library/src/main/java/com/ip/library/books/service/BookService.java index 6828d25..5aa71b9 100644 --- a/SpringApp/library/src/main/java/com/ip/library/books/service/BookService.java +++ b/SpringApp/library/src/main/java/com/ip/library/books/service/BookService.java @@ -3,8 +3,10 @@ package com.ip.library.books.service; import java.util.List; import java.util.Objects; import java.util.Optional; +import java.util.stream.StreamSupport; import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; import com.ip.library.books.model.BookEntity; import com.ip.library.books.repository.BookRepository; @@ -18,34 +20,37 @@ public class BookService { this.repository = repository; } + @Transactional(readOnly = true) public List getAll(Long typeId, Long authorId) { - List result = repository.getAll(); - if (!Objects.equals(typeId, 0L)){ - result = result.stream() - .filter(item -> item.getType().getId().equals(typeId)) - .toList(); + if (typeId <= 0L && authorId <= 0L) { + return StreamSupport.stream(repository.findAll().spliterator(), null).toList(); } - if (!Objects.equals(authorId, 0L)){ - result = result.stream() - .filter(item -> item.getAuthor().getId().equals(authorId)) - .toList(); + if (typeId <= 0L){ + return repository.findByAuthorId(authorId); } - return result; + if (authorId <= 0L){ + return repository.findByTypeId(typeId); + } + return repository.findByTypeIdAndAuthorId(typeId, authorId); } + @Transactional(readOnly = true) public List getAll() { return repository.getAll(); } + @Transactional(readOnly = true) public BookEntity get(Long id) { return Optional.ofNullable(repository.get(id)) .orElseThrow(() -> new NotFoundException(id)); } + @Transactional public BookEntity create(BookEntity entity) { return repository.create(entity); } + @Transactional public BookEntity update(Long id, BookEntity entity) { final BookEntity existsEntity = get(id); existsEntity.setName(entity.getName()); @@ -54,6 +59,7 @@ public class BookService { return repository.update(existsEntity); } + @Transactional public BookEntity delete(Long id) { final BookEntity existsEntity = get(id); return repository.delete(existsEntity); diff --git a/SpringApp/library/src/main/java/com/ip/library/core/configuration/Constants.java b/SpringApp/library/src/main/java/com/ip/library/core/configuration/Constants.java index 4e40f87..198d3a6 100644 --- a/SpringApp/library/src/main/java/com/ip/library/core/configuration/Constants.java +++ b/SpringApp/library/src/main/java/com/ip/library/core/configuration/Constants.java @@ -1,6 +1,8 @@ package com.ip.library.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/SpringApp/library/src/main/java/com/ip/library/core/error/NotFoundException.java b/SpringApp/library/src/main/java/com/ip/library/core/error/NotFoundException.java index ddabef7..028fc12 100644 --- a/SpringApp/library/src/main/java/com/ip/library/core/error/NotFoundException.java +++ b/SpringApp/library/src/main/java/com/ip/library/core/error/NotFoundException.java @@ -1,7 +1,7 @@ package com.ip.library.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/SpringApp/library/src/main/java/com/ip/library/core/model/BaseEntity.java b/SpringApp/library/src/main/java/com/ip/library/core/model/BaseEntity.java index 9e53df8..b942708 100644 --- a/SpringApp/library/src/main/java/com/ip/library/core/model/BaseEntity.java +++ b/SpringApp/library/src/main/java/com/ip/library/core/model/BaseEntity.java @@ -1,15 +1,23 @@ package com.ip.library.core.model; +import com.ip.library.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/SpringApp/library/src/main/java/com/ip/library/core/repository/CommonRepository.java b/SpringApp/library/src/main/java/com/ip/library/core/repository/CommonRepository.java deleted file mode 100644 index e72aa9a..0000000 --- a/SpringApp/library/src/main/java/com/ip/library/core/repository/CommonRepository.java +++ /dev/null @@ -1,17 +0,0 @@ -package com.ip.library.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/SpringApp/library/src/main/java/com/ip/library/core/repository/MapRepository.java b/SpringApp/library/src/main/java/com/ip/library/core/repository/MapRepository.java deleted file mode 100644 index e19f119..0000000 --- a/SpringApp/library/src/main/java/com/ip/library/core/repository/MapRepository.java +++ /dev/null @@ -1,57 +0,0 @@ -package com.ip.library.core.repository; - -import java.util.List; -import java.util.Map; -import java.util.TreeMap; - -import com.ip.library.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/SpringApp/library/src/main/java/com/ip/library/types/api/TypeDto.java b/SpringApp/library/src/main/java/com/ip/library/types/api/TypeDto.java index e7626b9..49583bf 100644 --- a/SpringApp/library/src/main/java/com/ip/library/types/api/TypeDto.java +++ b/SpringApp/library/src/main/java/com/ip/library/types/api/TypeDto.java @@ -3,13 +3,15 @@ package com.ip.library.types.api; import com.fasterxml.jackson.annotation.JsonProperty; import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.Size; public class TypeDto { + @JsonProperty(access = JsonProperty.Access.READ_ONLY) private Long id; @NotBlank + @Size(min = 5, max = 20) private String name; - - @JsonProperty(access = JsonProperty.Access.READ_ONLY) + public Long getId() { return id; } diff --git a/SpringApp/library/src/main/java/com/ip/library/types/model/TypeEntity.java b/SpringApp/library/src/main/java/com/ip/library/types/model/TypeEntity.java index 4e945a4..9bd403d 100644 --- a/SpringApp/library/src/main/java/com/ip/library/types/model/TypeEntity.java +++ b/SpringApp/library/src/main/java/com/ip/library/types/model/TypeEntity.java @@ -4,15 +4,21 @@ import java.util.Objects; import com.ip.library.core.model.BaseEntity; +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.Table; + +@Entity +@Table(name = "types") public class TypeEntity extends BaseEntity { + @Column(nullable = false, unique = true, length = 20) private String name; public TypeEntity() { super(); } - public TypeEntity(Long id, String name) { - super(id); + public TypeEntity(String name) { this.name = name; } diff --git a/SpringApp/library/src/main/java/com/ip/library/types/repository/TypeRepository.java b/SpringApp/library/src/main/java/com/ip/library/types/repository/TypeRepository.java index 1648303..1bf1394 100644 --- a/SpringApp/library/src/main/java/com/ip/library/types/repository/TypeRepository.java +++ b/SpringApp/library/src/main/java/com/ip/library/types/repository/TypeRepository.java @@ -1,10 +1,11 @@ package com.ip.library.types.repository; -import org.springframework.stereotype.Repository; +import java.util.Optional; + +import org.springframework.data.repository.CrudRepository; -import com.ip.library.core.repository.MapRepository; import com.ip.library.types.model.TypeEntity; -@Repository -public class TypeRepository extends MapRepository { +public interface TypeRepository extends CrudRepository { + Optional findByNameIgnoreCase(String name); } diff --git a/SpringApp/library/src/main/java/com/ip/library/types/service/TypeService.java b/SpringApp/library/src/main/java/com/ip/library/types/service/TypeService.java index 33f353f..526a337 100644 --- a/SpringApp/library/src/main/java/com/ip/library/types/service/TypeService.java +++ b/SpringApp/library/src/main/java/com/ip/library/types/service/TypeService.java @@ -1,9 +1,10 @@ package com.ip.library.types.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.ip.library.core.error.NotFoundException; import com.ip.library.types.model.TypeEntity; @@ -17,27 +18,49 @@ public class TypeService { this.repository = repository; } + private void checkNameUniqueness(String name){ + if (repository.findByNameIgnoreCase(name).isPresent()) { + throw new IllegalArgumentException( + String.format("Type with name %s already exists", name) + ); + } + } + + @Transactional(readOnly = true) public List getAll() { - return repository.getAll(); + return StreamSupport.stream(repository.findAll().spliterator(), false).toList(); } - public TypeEntity get(Long id) { - return Optional.ofNullable(repository.get(id)) - .orElseThrow(() -> new NotFoundException(id)); + @Transactional(readOnly = true) + public TypeEntity get(long id) { + return repository.findById(id) + .orElseThrow(() -> new NotFoundException(TypeEntity.class, id)); } + @Transactional public TypeEntity create(TypeEntity entity) { - return repository.create(entity); + if (entity == null) { + throw new IllegalArgumentException("Creating TypeEntity is null"); + } + checkNameUniqueness(entity.getName()); + return repository.save(entity); } + @Transactional public TypeEntity update(Long id, TypeEntity entity) { + if (entity == null) { + throw new IllegalArgumentException("Updating TypeEntity is null"); + } final TypeEntity existsEntity = get(id); + checkNameUniqueness(entity.getName()); existsEntity.setName(entity.getName()); - return repository.update(existsEntity); + return repository.save(existsEntity); } + @Transactional public TypeEntity delete(Long id) { final TypeEntity existsEntity = get(id); - return repository.delete(existsEntity); + repository.delete(existsEntity); + return existsEntity; } } diff --git a/SpringApp/library/src/main/java/com/ip/library/users/model/UserEntity.java b/SpringApp/library/src/main/java/com/ip/library/users/model/UserEntity.java index 7e9b559..c2eaac9 100644 --- a/SpringApp/library/src/main/java/com/ip/library/users/model/UserEntity.java +++ b/SpringApp/library/src/main/java/com/ip/library/users/model/UserEntity.java @@ -6,9 +6,18 @@ import java.util.Objects; import com.ip.library.books.model.BookEntity; import com.ip.library.core.model.BaseEntity; +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.Table; + +@Entity +@Table(name = "users") public class UserEntity extends BaseEntity { - private String name; + @Column(nullable = false, unique = true, length = 20) + private String login; + @Column(nullable = false, unique = true, length = 20) private String password; + @Column(nullable = false, unique = true, length = 20) private String role; private List books; @@ -16,20 +25,19 @@ public class UserEntity extends BaseEntity { super(); } - public UserEntity(Long id, String name, String password, String role, List books) { - super(id); - this.name = name; + public UserEntity(String name, String password, String role, List books) { + this.login = name; this.password = password; this.role = role; this.books = books; } - public String getName() { - return name; + public String getLogin() { + return login; } - public void setName(String name) { - this.name = name; + public void setLogin(String name) { + this.login = name; } public String getPassword() { @@ -58,7 +66,7 @@ public class UserEntity extends BaseEntity { @Override public int hashCode() { - return Objects.hash(id, name, password, role); + return Objects.hash(id, login, password, role); } @Override @@ -69,7 +77,7 @@ public class UserEntity extends BaseEntity { return false; final UserEntity other = (UserEntity) obj; return Objects.equals(other.getId(), id) - && Objects.equals(other.getName(), name) + && Objects.equals(other.getLogin(), login) && Objects.equals(other.getPassword(), password) && Objects.equals(other.getRole(), role) && Objects.equals(other.getBooks(), books); diff --git a/SpringApp/library/src/main/java/com/ip/library/users/service/UserService.java b/SpringApp/library/src/main/java/com/ip/library/users/service/UserService.java index 1629e26..e7d4f28 100644 --- a/SpringApp/library/src/main/java/com/ip/library/users/service/UserService.java +++ b/SpringApp/library/src/main/java/com/ip/library/users/service/UserService.java @@ -39,7 +39,7 @@ public class UserService { public UserEntity update(Long id, UserEntity entity) { final UserEntity existsEntity = get(id); - existsEntity.setName(entity.getName()); + existsEntity.setLogin(entity.getLogin()); return repository.update(existsEntity); } diff --git a/SpringApp/library/src/test/java/com/ip/library/UsersTests.java b/SpringApp/library/src/test/java/com/ip/library/UsersTests.java index 1c3afc2..9659d43 100644 --- a/SpringApp/library/src/test/java/com/ip/library/UsersTests.java +++ b/SpringApp/library/src/test/java/com/ip/library/UsersTests.java @@ -57,7 +57,7 @@ class UsersTests { @Test void createTest() { Assertions.assertEquals(3, userService.getAll().size()); - Assertions.assertEquals("user3", user.getName()); + Assertions.assertEquals("user3", user.getLogin()); Assertions.assertEquals("aqw2sed45", user.getPassword()); Assertions.assertEquals("user", user.getRole()); Assertions.assertEquals(0, user.getBooks().size()); @@ -76,7 +76,7 @@ class UsersTests { if (user.getId() != 1L) testId = 1L; else testId = 2L; - final String testName = user.getName() + "TEST"; + final String testName = user.getLogin() + "TEST"; final String testPassword = user.getPassword() + "TEST"; final String testRole = "admin"; List testBooks = new ArrayList(); @@ -85,7 +85,7 @@ class UsersTests { testPassword, testRole, testBooks)); Assertions.assertEquals(3, userService.getAll().size()); Assertions.assertNotEquals(testId, user.getId()); - Assertions.assertEquals(testName, user.getName()); + Assertions.assertEquals(testName, user.getLogin()); Assertions.assertNotEquals(testPassword, user.getPassword()); Assertions.assertNotEquals(testRole, user.getRole()); Assertions.assertEquals(0, user.getBooks().size()); @@ -96,7 +96,7 @@ class UsersTests { userService.delete(user.getId()); Assertions.assertEquals(2, userService.getAll().size()); final UserEntity newEntity = userService.create(new UserEntity(null, - user.getName(), user.getPassword(), null, null)); + user.getLogin(), user.getPassword(), null, null)); Assertions.assertEquals(3, userService.getAll().size()); Assertions.assertNotEquals(user.getId(), newEntity.getId()); } -- 2.25.1 From 8ef96d24941d8e1d26cd9185ab6ae5fe06b702cc Mon Sep 17 00:00:00 2001 From: Zakharov_Rostislav Date: Thu, 11 Apr 2024 14:56:45 +0400 Subject: [PATCH 02/21] lab-3 in process --- SpringApp/.vscode/settings.json | 3 +- .../authors/service/AuthorService.java | 6 +- .../ip/library/books/api/BookController.java | 2 +- .../com/ip/library/books/api/BookDto.java | 2 +- .../ip/library/books/service/BookService.java | 49 +++++++++------ .../ip/library/types/service/TypeService.java | 4 +- .../com/ip/library/users/api/UserDto.java | 26 +++----- .../ip/library/users/model/UserEntity.java | 21 ++++--- .../users/repository/UserRepository.java | 9 +-- .../ip/library/users/service/UserService.java | 59 +++++++++++++------ 10 files changed, 105 insertions(+), 76 deletions(-) diff --git a/SpringApp/.vscode/settings.json b/SpringApp/.vscode/settings.json index 572b0c0..26462a9 100644 --- a/SpringApp/.vscode/settings.json +++ b/SpringApp/.vscode/settings.json @@ -1,4 +1,5 @@ { "java.compile.nullAnalysis.mode": "automatic", - "java.configuration.updateBuildConfiguration": "interactive" + "java.configuration.updateBuildConfiguration": "interactive", + "java.dependency.packagePresentation": "hierarchical" } \ No newline at end of file diff --git a/SpringApp/library/src/main/java/com/ip/library/authors/service/AuthorService.java b/SpringApp/library/src/main/java/com/ip/library/authors/service/AuthorService.java index 800ff31..9ebe2cb 100644 --- a/SpringApp/library/src/main/java/com/ip/library/authors/service/AuthorService.java +++ b/SpringApp/library/src/main/java/com/ip/library/authors/service/AuthorService.java @@ -33,7 +33,7 @@ public class AuthorService { } @Transactional(readOnly = true) - public AuthorEntity get(Long id) { + public AuthorEntity get(long id) { return repository.findById(id) .orElseThrow(() -> new NotFoundException(AuthorEntity.class, id)); } @@ -48,7 +48,7 @@ public class AuthorService { } @Transactional - public AuthorEntity update(Long id, AuthorEntity entity) { + public AuthorEntity update(long id, AuthorEntity entity) { if (entity == null) { throw new IllegalArgumentException("Updating AuthorEntity is null"); } @@ -59,7 +59,7 @@ public class AuthorService { } @Transactional - public AuthorEntity delete(Long id) { + public AuthorEntity delete(long id) { final AuthorEntity existsEntity = get(id); repository.delete(existsEntity); return existsEntity; diff --git a/SpringApp/library/src/main/java/com/ip/library/books/api/BookController.java b/SpringApp/library/src/main/java/com/ip/library/books/api/BookController.java index 7ecb7a9..9aea2bd 100644 --- a/SpringApp/library/src/main/java/com/ip/library/books/api/BookController.java +++ b/SpringApp/library/src/main/java/com/ip/library/books/api/BookController.java @@ -52,7 +52,7 @@ public class BookController { public List getAll( @RequestParam(name = "typeId", defaultValue = "0") Long typeId, @RequestParam(name = "authorId", defaultValue = "0") Long authorId) { - return itemService.getAll(typeId, authorId).stream().map(this::toDto).toList(); + return itemService.getAllbyFilter(typeId, authorId).stream().map(this::toDto).toList(); } @GetMapping("/{id}") diff --git a/SpringApp/library/src/main/java/com/ip/library/books/api/BookDto.java b/SpringApp/library/src/main/java/com/ip/library/books/api/BookDto.java index c8e54e9..db6aad7 100644 --- a/SpringApp/library/src/main/java/com/ip/library/books/api/BookDto.java +++ b/SpringApp/library/src/main/java/com/ip/library/books/api/BookDto.java @@ -7,6 +7,7 @@ import jakarta.validation.constraints.NotBlank; import jakarta.validation.constraints.NotNull; public class BookDto { + @JsonProperty(access = JsonProperty.Access.READ_ONLY) private Long id; @NotBlank private String name; @@ -17,7 +18,6 @@ public class BookDto { @Min(1) private Long authorId; - @JsonProperty(access = JsonProperty.Access.READ_ONLY) public Long getId() { return id; } diff --git a/SpringApp/library/src/main/java/com/ip/library/books/service/BookService.java b/SpringApp/library/src/main/java/com/ip/library/books/service/BookService.java index 5aa71b9..18e8f2e 100644 --- a/SpringApp/library/src/main/java/com/ip/library/books/service/BookService.java +++ b/SpringApp/library/src/main/java/com/ip/library/books/service/BookService.java @@ -1,8 +1,6 @@ package com.ip.library.books.service; import java.util.List; -import java.util.Objects; -import java.util.Optional; import java.util.stream.StreamSupport; import org.springframework.stereotype.Service; @@ -20,10 +18,23 @@ public class BookService { this.repository = repository; } + private void checkNameUniqueness(String name){ + if (repository.findByNameIgnoreCase(name).isPresent()) { + throw new IllegalArgumentException( + String.format("Book with name %s already exists", name) + ); + } + } + @Transactional(readOnly = true) - public List getAll(Long typeId, Long authorId) { + public List getAll() { + return StreamSupport.stream(repository.findAll().spliterator(), false).toList(); + } + + @Transactional(readOnly = true) + public List getAllbyFilter(long typeId, long authorId) { if (typeId <= 0L && authorId <= 0L) { - return StreamSupport.stream(repository.findAll().spliterator(), null).toList(); + return getAll(); } if (typeId <= 0L){ return repository.findByAuthorId(authorId); @@ -35,33 +46,37 @@ public class BookService { } @Transactional(readOnly = true) - public List getAll() { - return repository.getAll(); - } - - @Transactional(readOnly = true) - public BookEntity get(Long id) { - return Optional.ofNullable(repository.get(id)) - .orElseThrow(() -> new NotFoundException(id)); + public BookEntity get(long id) { + return repository.findById(id) + .orElseThrow(() -> new NotFoundException(BookEntity.class, id)); } @Transactional public BookEntity create(BookEntity entity) { - return repository.create(entity); + if (entity == null) { + throw new IllegalArgumentException("Creating BookEntity is null"); + } + checkNameUniqueness(entity.getName()); + return repository.save(entity); } @Transactional - public BookEntity update(Long id, BookEntity entity) { + public BookEntity update(long id, BookEntity entity) { + if (entity == null) { + throw new IllegalArgumentException("Updating BookEntity is null"); + } final BookEntity existsEntity = get(id); + checkNameUniqueness(entity.getName()); existsEntity.setName(entity.getName()); existsEntity.setType(entity.getType()); existsEntity.setAuthor(entity.getAuthor()); - return repository.update(existsEntity); + return repository.save(existsEntity); } @Transactional - public BookEntity delete(Long id) { + public BookEntity delete(long id) { final BookEntity existsEntity = get(id); - return repository.delete(existsEntity); + repository.delete(existsEntity); + return existsEntity; } } diff --git a/SpringApp/library/src/main/java/com/ip/library/types/service/TypeService.java b/SpringApp/library/src/main/java/com/ip/library/types/service/TypeService.java index 526a337..82eff00 100644 --- a/SpringApp/library/src/main/java/com/ip/library/types/service/TypeService.java +++ b/SpringApp/library/src/main/java/com/ip/library/types/service/TypeService.java @@ -47,7 +47,7 @@ public class TypeService { } @Transactional - public TypeEntity update(Long id, TypeEntity entity) { + public TypeEntity update(long id, TypeEntity entity) { if (entity == null) { throw new IllegalArgumentException("Updating TypeEntity is null"); } @@ -58,7 +58,7 @@ public class TypeService { } @Transactional - public TypeEntity delete(Long id) { + public TypeEntity delete(long id) { final TypeEntity existsEntity = get(id); repository.delete(existsEntity); return existsEntity; diff --git a/SpringApp/library/src/main/java/com/ip/library/users/api/UserDto.java b/SpringApp/library/src/main/java/com/ip/library/users/api/UserDto.java index c5070f7..a2854df 100644 --- a/SpringApp/library/src/main/java/com/ip/library/users/api/UserDto.java +++ b/SpringApp/library/src/main/java/com/ip/library/users/api/UserDto.java @@ -5,20 +5,23 @@ import java.util.List; import com.fasterxml.jackson.annotation.JsonProperty; import jakarta.validation.constraints.NotBlank; -import jakarta.validation.constraints.NotNull; +import jakarta.validation.constraints.Size; public class UserDto { + @JsonProperty(access = JsonProperty.Access.READ_ONLY) private Long id; @NotBlank + @Size(min = 5, max = 20) private String name; + @JsonProperty(access = JsonProperty.Access.READ_ONLY) @NotBlank + @Size(min = 5, max = 20) private String password; - @NotBlank - private String role; - @NotNull - private List books; - @JsonProperty(access = JsonProperty.Access.READ_ONLY) + @NotBlank + @Size(min = 4, max = 20) + private String role; + public Long getId() { return id; } @@ -35,7 +38,6 @@ public class UserDto { this.name = name; } - @JsonProperty(access = JsonProperty.Access.READ_ONLY) public String getPassword() { return password; } @@ -44,7 +46,6 @@ public class UserDto { this.password = password; } - @JsonProperty(access = JsonProperty.Access.READ_ONLY) public String getRole() { return role; } @@ -52,13 +53,4 @@ public class UserDto { public void setRole(String role) { this.role = role; } - - @JsonProperty(access = JsonProperty.Access.READ_ONLY) - public List getBooks() { - return books; - } - - public void setBooks(List books) { - this.books = books; - } } diff --git a/SpringApp/library/src/main/java/com/ip/library/users/model/UserEntity.java b/SpringApp/library/src/main/java/com/ip/library/users/model/UserEntity.java index c2eaac9..69fc764 100644 --- a/SpringApp/library/src/main/java/com/ip/library/users/model/UserEntity.java +++ b/SpringApp/library/src/main/java/com/ip/library/users/model/UserEntity.java @@ -1,7 +1,8 @@ package com.ip.library.users.model; -import java.util.List; +import java.util.HashSet; import java.util.Objects; +import java.util.Set; import com.ip.library.books.model.BookEntity; import com.ip.library.core.model.BaseEntity; @@ -15,21 +16,19 @@ import jakarta.persistence.Table; public class UserEntity extends BaseEntity { @Column(nullable = false, unique = true, length = 20) private String login; - @Column(nullable = false, unique = true, length = 20) + @Column(nullable = false, unique = false, length = 20) private String password; - @Column(nullable = false, unique = true, length = 20) - private String role; - private List books; + @Column(nullable = false, unique = false, length = 20) + private String role = "user"; + private Set books = new HashSet<>(); public UserEntity() { super(); } - public UserEntity(String name, String password, String role, List books) { - this.login = name; + public UserEntity(String login, String password) { + this.login = login; this.password = password; - this.role = role; - this.books = books; } public String getLogin() { @@ -56,11 +55,11 @@ public class UserEntity extends BaseEntity { this.role = role; } - public List getBooks() { + public Set getBooks() { return books; } - public void setBooks(List books) { + public void setBooks(Set books) { this.books = books; } diff --git a/SpringApp/library/src/main/java/com/ip/library/users/repository/UserRepository.java b/SpringApp/library/src/main/java/com/ip/library/users/repository/UserRepository.java index 65e1f8f..d1f4470 100644 --- a/SpringApp/library/src/main/java/com/ip/library/users/repository/UserRepository.java +++ b/SpringApp/library/src/main/java/com/ip/library/users/repository/UserRepository.java @@ -1,10 +1,11 @@ package com.ip.library.users.repository; -import org.springframework.stereotype.Repository; +import java.util.Optional; + +import org.springframework.data.repository.CrudRepository; -import com.ip.library.core.repository.MapRepository; import com.ip.library.users.model.UserEntity; -@Repository -public class UserRepository extends MapRepository { +public interface UserRepository extends CrudRepository { + Optional findByLoginIgnoreCase(String login); } diff --git a/SpringApp/library/src/main/java/com/ip/library/users/service/UserService.java b/SpringApp/library/src/main/java/com/ip/library/users/service/UserService.java index e7d4f28..190503c 100644 --- a/SpringApp/library/src/main/java/com/ip/library/users/service/UserService.java +++ b/SpringApp/library/src/main/java/com/ip/library/users/service/UserService.java @@ -3,8 +3,10 @@ package com.ip.library.users.service; import java.util.ArrayList; 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.ip.library.books.model.BookEntity; import com.ip.library.books.service.BookService; @@ -21,58 +23,77 @@ public class UserService { this.repository = repository; this.bookService = bookService; } + + private void checkLoginUniqueness(String name){ + if (repository.findByLoginIgnoreCase(name).isPresent()) { + throw new IllegalArgumentException( + String.format("Type with name %s already exists", name) + ); + } + } + @Transactional(readOnly = true) public List getAll() { - return repository.getAll(); + return StreamSupport.stream(repository.findAll().spliterator(), false).toList(); } - public UserEntity get(Long id) { - return Optional.ofNullable(repository.get(id)) - .orElseThrow(() -> new NotFoundException(id)); + @Transactional(readOnly = true) + public UserEntity get(long id) { + return repository.findById(id) + .orElseThrow(() -> new NotFoundException(UserEntity.class, id)); } + @Transactional public UserEntity create(UserEntity entity) { - entity.setRole("user"); - entity.setBooks(new ArrayList<>()); - return repository.create(entity); + checkLoginUniqueness(entity.getLogin()); + return repository.save(entity); } - public UserEntity update(Long id, UserEntity entity) { + @Transactional + public UserEntity update(long id, UserEntity entity) { final UserEntity existsEntity = get(id); + checkLoginUniqueness(entity.getLogin()); existsEntity.setLogin(entity.getLogin()); - return repository.update(existsEntity); + return repository.save(existsEntity); } - public UserEntity delete(Long id) { + @Transactional + public UserEntity delete(long id) { final UserEntity existsEntity = get(id); - return repository.delete(existsEntity); + repository.delete(existsEntity); + return existsEntity; } - public UserEntity giveAdminRole(Long id) { + @Transactional + public UserEntity giveAdminRole(long id) { final UserEntity existsEntity = get(id); existsEntity.setRole("admin"); - return repository.update(existsEntity); + return repository.save(existsEntity); } - public UserEntity giveUserRole(Long id) { + @Transactional + public UserEntity giveUserRole(long id) { final UserEntity existsEntity = get(id); existsEntity.setRole("user"); - return repository.update(existsEntity); + return repository.save(existsEntity); } - public UserEntity changePassword(Long id, String newPassword) { + @Transactional + public UserEntity changePassword(long id, String newPassword) { final UserEntity existsEntity = get(id); existsEntity.setPassword(newPassword); - return repository.update(existsEntity); + return repository.save(existsEntity); } - public boolean addBook(Long id, Long bookId) { + @Transactional + public boolean addBook(long id, long bookId) { final UserEntity existsEntity = get(id); final BookEntity book = bookService.get(bookId); return existsEntity.getBooks().add(book); } - public boolean removeBook(Long id, Long bookId) { + @Transactional + public boolean removeBook(long id, long bookId) { final UserEntity existsEntity = get(id); final BookEntity book = bookService.get(bookId); return existsEntity.getBooks().remove(book); -- 2.25.1 From bc1395933a2bbdcb7f08480043799ad93a3ef35d Mon Sep 17 00:00:00 2001 From: Zakharov_Rostislav Date: Mon, 15 Apr 2024 15:46:40 +0400 Subject: [PATCH 03/21] lab-3 some mistakes --- .../com/ip/library/LibraryApplication.java | 22 +++---- .../authors/service/AuthorService.java | 1 - .../com/ip/library/users/api/UserDto.java | 2 - .../ip/library/users/service/UserService.java | 2 - .../java/com/ip/library/AuthorsTests.java | 17 ++--- .../test/java/com/ip/library/BooksTests.java | 31 +++++---- .../java/com/ip/library/FavoritiesTests.java | 64 ------------------- .../test/java/com/ip/library/TypesTests.java | 21 +++--- .../test/java/com/ip/library/UserEntity.java | 5 -- .../test/java/com/ip/library/UsersTests.java | 53 +++++++-------- 10 files changed, 71 insertions(+), 147 deletions(-) delete mode 100644 SpringApp/library/src/test/java/com/ip/library/FavoritiesTests.java delete mode 100644 SpringApp/library/src/test/java/com/ip/library/UserEntity.java diff --git a/SpringApp/library/src/main/java/com/ip/library/LibraryApplication.java b/SpringApp/library/src/main/java/com/ip/library/LibraryApplication.java index 323416a..fe1bcc5 100644 --- a/SpringApp/library/src/main/java/com/ip/library/LibraryApplication.java +++ b/SpringApp/library/src/main/java/com/ip/library/LibraryApplication.java @@ -43,23 +43,23 @@ public class LibraryApplication implements CommandLineRunner { public void run(String... args) throws Exception { if (args.length > 0 && args[0].equals("--populate")) { log.info("Create default types values"); - final var type1 = typeService.create(new TypeEntity(null, "type1")); - final var type2 = typeService.create(new TypeEntity(null, "type2")); + final var type1 = typeService.create(new TypeEntity("type1")); + final var type2 = typeService.create(new TypeEntity("type2")); log.info("Create default authors values"); - final var author1 = authorService.create(new AuthorEntity(null, "author1")); - final var author2 = authorService.create(new AuthorEntity(null, "author2")); + final var author1 = authorService.create(new AuthorEntity("author1")); + final var author2 = authorService.create(new AuthorEntity("author2")); log.info("Create default books values"); - final var book1 = bookService.create(new BookEntity(null, "book1", type1, author1)); - final var book2 = bookService.create(new BookEntity(null, "book2", type1, author2)); - final var book3 = bookService.create(new BookEntity(null, "book3", type2, author1)); - final var book4 = bookService.create(new BookEntity(null, "book4", type2, author2)); + final var book1 = bookService.create(new BookEntity("book1", type1, author1)); + final var book2 = bookService.create(new BookEntity("book2", type1, author2)); + final var book3 = bookService.create(new BookEntity("book3", type2, author1)); + final var book4 = bookService.create(new BookEntity("book4", type2, author2)); log.info("Create default users values"); - final var user1 = userService.create(new UserEntity(null, "user1", "123", null, null)); - final var user2 = userService.create(new UserEntity(null, "user2", "123", null, null )); - final var admin1 = userService.create(new UserEntity(null, "admin1", "123", null, null)); + final var user1 = userService.create(new UserEntity("user1", "123")); + final var user2 = userService.create(new UserEntity("user2", "123")); + final var admin1 = userService.create(new UserEntity("admin1", "123")); userService.giveAdminRole(admin1.getId()); } } diff --git a/SpringApp/library/src/main/java/com/ip/library/authors/service/AuthorService.java b/SpringApp/library/src/main/java/com/ip/library/authors/service/AuthorService.java index 9ebe2cb..27eee8f 100644 --- a/SpringApp/library/src/main/java/com/ip/library/authors/service/AuthorService.java +++ b/SpringApp/library/src/main/java/com/ip/library/authors/service/AuthorService.java @@ -1,7 +1,6 @@ package com.ip.library.authors.service; import java.util.List; -import java.util.Optional; import java.util.stream.StreamSupport; import org.springframework.stereotype.Service; diff --git a/SpringApp/library/src/main/java/com/ip/library/users/api/UserDto.java b/SpringApp/library/src/main/java/com/ip/library/users/api/UserDto.java index a2854df..747ba0e 100644 --- a/SpringApp/library/src/main/java/com/ip/library/users/api/UserDto.java +++ b/SpringApp/library/src/main/java/com/ip/library/users/api/UserDto.java @@ -1,7 +1,5 @@ package com.ip.library.users.api; -import java.util.List; - import com.fasterxml.jackson.annotation.JsonProperty; import jakarta.validation.constraints.NotBlank; diff --git a/SpringApp/library/src/main/java/com/ip/library/users/service/UserService.java b/SpringApp/library/src/main/java/com/ip/library/users/service/UserService.java index 190503c..9280612 100644 --- a/SpringApp/library/src/main/java/com/ip/library/users/service/UserService.java +++ b/SpringApp/library/src/main/java/com/ip/library/users/service/UserService.java @@ -1,8 +1,6 @@ package com.ip.library.users.service; -import java.util.ArrayList; import java.util.List; -import java.util.Optional; import java.util.stream.StreamSupport; import org.springframework.stereotype.Service; diff --git a/SpringApp/library/src/test/java/com/ip/library/AuthorsTests.java b/SpringApp/library/src/test/java/com/ip/library/AuthorsTests.java index 8015c9c..014b62d 100644 --- a/SpringApp/library/src/test/java/com/ip/library/AuthorsTests.java +++ b/SpringApp/library/src/test/java/com/ip/library/AuthorsTests.java @@ -25,9 +25,9 @@ class AuthorsTests { @BeforeEach void createData() { removeData(); - authorService.create(new AuthorEntity(null, "author1")); - authorService.create(new AuthorEntity(null, "author2")); - entity = authorService.create(new AuthorEntity(null, "author3")); + authorService.create(new AuthorEntity("author1")); + authorService.create(new AuthorEntity("author2")); + entity = authorService.create(new AuthorEntity("author3")); } @Test @@ -44,14 +44,11 @@ class AuthorsTests { @Test void updateTest() { - final Long testId; - if (entity.getId() != 1L) - testId = 1L; - else testId = 2L; + final Long oldId = entity.getId(); final String testName = entity.getName() + "TEST"; - entity = authorService.update(entity.getId(), new AuthorEntity(testId, testName)); + entity = authorService.update(oldId, new AuthorEntity(testName)); Assertions.assertEquals(3, authorService.getAll().size()); - Assertions.assertNotEquals(testId, entity.getId()); + Assertions.assertEquals(oldId, entity.getId()); Assertions.assertEquals(testName, entity.getName()); } @@ -59,7 +56,7 @@ class AuthorsTests { void deleteTest() { authorService.delete(entity.getId()); Assertions.assertEquals(2, authorService.getAll().size()); - final AuthorEntity newEntity = authorService.create(new AuthorEntity(null, entity.getName())); + final AuthorEntity newEntity = authorService.create(new AuthorEntity(entity.getName())); Assertions.assertEquals(3, authorService.getAll().size()); Assertions.assertNotEquals(entity.getId(), newEntity.getId()); } diff --git a/SpringApp/library/src/test/java/com/ip/library/BooksTests.java b/SpringApp/library/src/test/java/com/ip/library/BooksTests.java index 3041484..f3addf7 100644 --- a/SpringApp/library/src/test/java/com/ip/library/BooksTests.java +++ b/SpringApp/library/src/test/java/com/ip/library/BooksTests.java @@ -37,13 +37,13 @@ class BooksTests { @BeforeEach void createData() { removeData(); - type = typeService.create(new TypeEntity(null, "type1")); - var type2 = typeService.create(new TypeEntity(null, "type2")); - author = authorService.create(new AuthorEntity(null, "author1")); - var author2 = authorService.create(new AuthorEntity(null, "author2")); - bookService.create(new BookEntity(null, "book1", type, author2)); - bookService.create(new BookEntity(null, "book2", type2, author)); - book = bookService.create(new BookEntity(null, "book3", type, author)); + type = typeService.create(new TypeEntity("type1")); + var type2 = typeService.create(new TypeEntity("type2")); + author = authorService.create(new AuthorEntity("author1")); + var author2 = authorService.create(new AuthorEntity("author2")); + bookService.create(new BookEntity("book1", type, author2)); + bookService.create(new BookEntity("book2", type2, author)); + book = bookService.create(new BookEntity("book3", type, author)); } @Test @@ -62,16 +62,14 @@ class BooksTests { @Test void updateTest() { - final Long testId; - if (book.getId() != 1L) - testId = 1L; - else testId = 2L; final String testName = book.getName() + "TEST"; - final TypeEntity testType = typeService.create(new TypeEntity(null, book.getType().getName() + "TEST")); - final AuthorEntity testAuthor = authorService.create(new AuthorEntity(null, book.getAuthor().getName() + "TEST")); - book = bookService.update(book.getId(), new BookEntity(testId, testName, testType, testAuthor)); + final TypeEntity testType = typeService.create( + new TypeEntity(book.getType().getName() + "TEST")); + final AuthorEntity testAuthor = authorService.create( + new AuthorEntity(book.getAuthor().getName() + "TEST")); + book = bookService.update(book.getId(), new BookEntity( + testName, testType, testAuthor)); Assertions.assertEquals(3, bookService.getAll().size()); - Assertions.assertNotEquals(testId, book.getId()); Assertions.assertEquals(testName, book.getName()); Assertions.assertEquals(testType, book.getType()); Assertions.assertEquals(testAuthor, book.getAuthor()); @@ -81,7 +79,8 @@ class BooksTests { void deleteTest() { bookService.delete(book.getId()); Assertions.assertEquals(2, bookService.getAll().size()); - final BookEntity newEntity = bookService.create(new BookEntity(null, book.getName(), book.getType(), book.getAuthor())); + final BookEntity newEntity = bookService.create( + new BookEntity(book.getName(), book.getType(), book.getAuthor())); Assertions.assertEquals(3, bookService.getAll().size()); Assertions.assertNotEquals(book.getId(), newEntity.getId()); } diff --git a/SpringApp/library/src/test/java/com/ip/library/FavoritiesTests.java b/SpringApp/library/src/test/java/com/ip/library/FavoritiesTests.java deleted file mode 100644 index b061e45..0000000 --- a/SpringApp/library/src/test/java/com/ip/library/FavoritiesTests.java +++ /dev/null @@ -1,64 +0,0 @@ -package com.ip.library; - -import org.junit.jupiter.api.AfterEach; -import org.junit.jupiter.api.Assertions; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.context.SpringBootTest; - -import com.ip.library.authors.model.AuthorEntity; -import com.ip.library.authors.service.AuthorService; -import com.ip.library.books.model.BookEntity; -import com.ip.library.books.service.BookService; -import com.ip.library.types.model.TypeEntity; -import com.ip.library.users.model.UserEntity; -import com.ip.library.types.service.TypeService; -import com.ip.library.users.service.UserService; - -@SpringBootTest -class FavoritiesTests { - @Autowired - private BookService bookService; - @Autowired - private TypeService typeService; - @Autowired - private AuthorService authorService; - @Autowired - private UserService userService; - private UserEntity user; - private BookEntity book1; - private BookEntity book2; - - @AfterEach - void removeData() { - authorService.getAll().forEach(item -> authorService.delete(item.getId())); - bookService.getAll().forEach(item -> bookService.delete(item.getId())); - typeService.getAll().forEach(item -> typeService.delete(item.getId())); - userService.getAll().forEach(item -> userService.delete(item.getId())); - } - - @BeforeEach - void createData() { - removeData(); - var type = typeService.create(new TypeEntity(null, "type1")); - var author = authorService.create(new AuthorEntity(null, "author1")); - user = userService.create(new UserEntity(null, "user", "password", null, null)); - book1 = bookService.create(new BookEntity(null, "book1", type, author)); - book2 = bookService.create(new BookEntity(null, "book2", type, author)); - } - - @Test - void addAndRemoveBooksTest() { - Assertions.assertEquals(0, user.getBooks().size()); - userService.addBook(user.getId(), book1.getId()); - Assertions.assertEquals(1, user.getBooks().size()); - userService.addBook(user.getId(), book2.getId()); - Assertions.assertEquals(2, user.getBooks().size()); - Assertions.assertEquals(2, user.getBooks().size()); - userService.removeBook(user.getId(), book1.getId()); - Assertions.assertEquals(1, user.getBooks().size()); - userService.removeBook(user.getId(), book2.getId()); - Assertions.assertEquals(0, user.getBooks().size()); - } -} diff --git a/SpringApp/library/src/test/java/com/ip/library/TypesTests.java b/SpringApp/library/src/test/java/com/ip/library/TypesTests.java index da03ba3..9c0d5bb 100644 --- a/SpringApp/library/src/test/java/com/ip/library/TypesTests.java +++ b/SpringApp/library/src/test/java/com/ip/library/TypesTests.java @@ -25,9 +25,9 @@ class TypesTests { @BeforeEach void createData() { removeData(); - typeService.create(new TypeEntity(null, "type1")); - typeService.create(new TypeEntity(null, "type2")); - entity = typeService.create(new TypeEntity(null, "type3")); + typeService.create(new TypeEntity("type1")); + typeService.create(new TypeEntity("type2")); + entity = typeService.create(new TypeEntity("type3")); } @Test @@ -39,19 +39,17 @@ class TypesTests { @Test void getTest() { Assertions.assertEquals(entity, typeService.get(entity.getId())); - Assertions.assertThrows(NotFoundException.class, () -> typeService.get(0L)); + Assertions.assertThrows( + NotFoundException.class, () -> typeService.get(0L)); } @Test void updateTest() { - final Long testId; - if (entity.getId() != 1L) - testId = 1L; - else testId = 2L; + final Long oldId = entity.getId(); final String testName = entity.getName() + "TEST"; - entity = typeService.update(entity.getId(), new TypeEntity(testId, testName)); + entity = typeService.update(oldId, new TypeEntity(testName)); Assertions.assertEquals(3, typeService.getAll().size()); - Assertions.assertNotEquals(testId, entity.getId()); + Assertions.assertEquals(oldId, entity.getId()); Assertions.assertEquals(testName, entity.getName()); } @@ -59,7 +57,8 @@ class TypesTests { void deleteTest() { typeService.delete(entity.getId()); Assertions.assertEquals(2, typeService.getAll().size()); - final TypeEntity newEntity = typeService.create(new TypeEntity(null, entity.getName())); + final TypeEntity newEntity = typeService.create( + new TypeEntity(entity.getName())); Assertions.assertEquals(3, typeService.getAll().size()); Assertions.assertNotEquals(entity.getId(), newEntity.getId()); } diff --git a/SpringApp/library/src/test/java/com/ip/library/UserEntity.java b/SpringApp/library/src/test/java/com/ip/library/UserEntity.java deleted file mode 100644 index 7e3437b..0000000 --- a/SpringApp/library/src/test/java/com/ip/library/UserEntity.java +++ /dev/null @@ -1,5 +0,0 @@ -package com.ip.library; - -public class UserEntity { - -} diff --git a/SpringApp/library/src/test/java/com/ip/library/UsersTests.java b/SpringApp/library/src/test/java/com/ip/library/UsersTests.java index 9659d43..a648407 100644 --- a/SpringApp/library/src/test/java/com/ip/library/UsersTests.java +++ b/SpringApp/library/src/test/java/com/ip/library/UsersTests.java @@ -1,8 +1,5 @@ package com.ip.library; -import java.util.ArrayList; -import java.util.List; - import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.BeforeEach; @@ -31,7 +28,8 @@ class UsersTests { @Autowired private UserService userService; private UserEntity user; - private BookEntity book; + private BookEntity book1; + private BookEntity book2; @AfterEach void removeData() { @@ -44,14 +42,13 @@ class UsersTests { @BeforeEach void createData() { removeData(); - var type1 = typeService.create(new TypeEntity(null, "type1")); - var author1 = authorService.create(new AuthorEntity(null, "author1")); - book = bookService.create(new BookEntity(null, "book1", type1, author1)); - List books = new ArrayList(); - books.add(book); - userService.create(new UserEntity(null, "user1", "123", "user", null)); - userService.create(new UserEntity(null, "user2", "456", "user", null)); - user = userService.create(new UserEntity(null, "user3", "aqw2sed45", "admin", books)); + var type = typeService.create(new TypeEntity("type1")); + var author = authorService.create(new AuthorEntity("author1")); + book1 = bookService.create(new BookEntity("book1", type, author)); + book2 = bookService.create(new BookEntity("book2", type, author)); + userService.create(new UserEntity("user1", "123")); + userService.create(new UserEntity("user2", "456")); + user = userService.create(new UserEntity("user3", "aqw2sed45")); } @Test @@ -72,22 +69,14 @@ class UsersTests { @Test void updateTest() { - final Long testId; - if (user.getId() != 1L) - testId = 1L; - else testId = 2L; + final Long oldId = user.getId(); final String testName = user.getLogin() + "TEST"; final String testPassword = user.getPassword() + "TEST"; - final String testRole = "admin"; - List testBooks = new ArrayList(); - testBooks.add(book); - user = userService.update(user.getId(), new UserEntity(testId, testName, - testPassword, testRole, testBooks)); + user = userService.update(oldId, new UserEntity(testName, testPassword)); Assertions.assertEquals(3, userService.getAll().size()); - Assertions.assertNotEquals(testId, user.getId()); + Assertions.assertEquals(oldId, user.getId()); Assertions.assertEquals(testName, user.getLogin()); Assertions.assertNotEquals(testPassword, user.getPassword()); - Assertions.assertNotEquals(testRole, user.getRole()); Assertions.assertEquals(0, user.getBooks().size()); } @@ -95,8 +84,8 @@ class UsersTests { void deleteTest() { userService.delete(user.getId()); Assertions.assertEquals(2, userService.getAll().size()); - final UserEntity newEntity = userService.create(new UserEntity(null, - user.getLogin(), user.getPassword(), null, null)); + final UserEntity newEntity = userService.create( + new UserEntity(user.getLogin(), user.getPassword())); Assertions.assertEquals(3, userService.getAll().size()); Assertions.assertNotEquals(user.getId(), newEntity.getId()); } @@ -116,4 +105,18 @@ class UsersTests { userService.giveUserRole(user.getId()); Assertions.assertEquals("user", user.getRole()); } + + @Test + void BooksTest() { + Assertions.assertEquals(0, user.getBooks().size()); + userService.addBook(user.getId(), book1.getId()); + Assertions.assertEquals(1, user.getBooks().size()); + userService.addBook(user.getId(), book2.getId()); + Assertions.assertEquals(2, user.getBooks().size()); + Assertions.assertEquals(2, user.getBooks().size()); + userService.removeBook(user.getId(), book1.getId()); + Assertions.assertEquals(1, user.getBooks().size()); + userService.removeBook(user.getId(), book2.getId()); + Assertions.assertEquals(0, user.getBooks().size()); + } } -- 2.25.1 From 4aedaec175fdbd58295da9e0ea910769e2a880f1 Mon Sep 17 00:00:00 2001 From: Zakharov_Rostislav Date: Mon, 15 Apr 2024 19:53:42 +0400 Subject: [PATCH 04/21] lab-3 it is work --- .../ip/library/books/model/BookEntity.java | 38 ++++++++- .../favorites/api/FavoriteController.java | 56 +++++++++++++ .../favorites/service/FavoriteService.java | 47 +++++++++++ .../ip/library/users/api/UserController.java | 12 +-- .../ip/library/users/model/UserEntity.java | 29 +++++++ .../ip/library/users/service/UserService.java | 20 +---- .../test/java/com/ip/library/BooksTests.java | 1 + .../java/com/ip/library/FavoritesTests.java | 82 +++++++++++++++++++ .../test/java/com/ip/library/UsersTests.java | 41 +--------- 9 files changed, 257 insertions(+), 69 deletions(-) create mode 100644 SpringApp/library/src/main/java/com/ip/library/favorites/api/FavoriteController.java create mode 100644 SpringApp/library/src/main/java/com/ip/library/favorites/service/FavoriteService.java create mode 100644 SpringApp/library/src/test/java/com/ip/library/FavoritesTests.java diff --git a/SpringApp/library/src/main/java/com/ip/library/books/model/BookEntity.java b/SpringApp/library/src/main/java/com/ip/library/books/model/BookEntity.java index 85831e7..01d7365 100644 --- a/SpringApp/library/src/main/java/com/ip/library/books/model/BookEntity.java +++ b/SpringApp/library/src/main/java/com/ip/library/books/model/BookEntity.java @@ -1,14 +1,20 @@ package com.ip.library.books.model; +import java.util.HashSet; import java.util.Objects; +import java.util.Set; import com.ip.library.core.model.BaseEntity; import com.ip.library.types.model.TypeEntity; +import com.ip.library.users.model.UserEntity; import jakarta.persistence.Column; import jakarta.persistence.Entity; +import jakarta.persistence.FetchType; import jakarta.persistence.JoinColumn; +import jakarta.persistence.ManyToMany; import jakarta.persistence.ManyToOne; +import jakarta.persistence.OrderBy; import jakarta.persistence.Table; import com.ip.library.authors.model.AuthorEntity; @@ -20,10 +26,15 @@ public class BookEntity extends BaseEntity { private String name; @ManyToOne @JoinColumn(name = "typeId", nullable = false) + @OrderBy("id ASC") private TypeEntity type; @ManyToOne @JoinColumn(name = "authorId", nullable = false) + @OrderBy("id ASC") private AuthorEntity author; + @ManyToMany(mappedBy = "books", fetch = FetchType.EAGER) + @OrderBy("id ASC") + private Set users = new HashSet<>(); public BookEntity() { super(); @@ -59,6 +70,30 @@ public class BookEntity extends BaseEntity { this.author = author; } + public Set getUsers() { + return users; + } + + public void setUsers(Set users) { + this.users = users; + } + + public UserEntity addUser(UserEntity user) { + users.add(user); + if (!user.getBooks().contains(this)){ + user.getBooks().add(this); + } + return user; + } + + public UserEntity removeUser(UserEntity user) { + users.remove(user); + if (user.getBooks().contains(this)) { + user.getBooks().remove(this); + } + return user; + } + @Override public int hashCode() { return Objects.hash(id, type, author); @@ -74,6 +109,7 @@ public class BookEntity extends BaseEntity { return Objects.equals(other.getId(), id) && Objects.equals(other.getName(), name) && Objects.equals(other.getType(), type) - && Objects.equals(other.getAuthor(), author); + && Objects.equals(other.getAuthor(), author) + && Objects.equals(other.getUsers(), users); } } diff --git a/SpringApp/library/src/main/java/com/ip/library/favorites/api/FavoriteController.java b/SpringApp/library/src/main/java/com/ip/library/favorites/api/FavoriteController.java new file mode 100644 index 0000000..317a931 --- /dev/null +++ b/SpringApp/library/src/main/java/com/ip/library/favorites/api/FavoriteController.java @@ -0,0 +1,56 @@ +package com.ip.library.favorites.api; + +import org.springframework.web.bind.annotation.RestController; + +import java.util.List; + +import org.modelmapper.ModelMapper; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestMapping; + +import com.ip.library.books.api.BookDto; +import com.ip.library.books.model.BookEntity; +import com.ip.library.core.configuration.Constants; +import com.ip.library.favorites.service.FavoriteService; + + +@RestController +@RequestMapping(Constants.API_URL + "/favorities") +public class FavoriteController { + private FavoriteService favoriteService; + private final ModelMapper modelMapper; + + public FavoriteController (FavoriteService favorityService, ModelMapper modelMapper) { + this.favoriteService = favorityService; + this.modelMapper = modelMapper; + } + private BookDto toBookDto (BookEntity entity) { + return modelMapper.map(entity, BookDto.class); + } + + @GetMapping("/user/{userId}/books/{bookId}") + public boolean addFavorite( + @PathVariable(name = "userId") Long userId, + @PathVariable(name = "bookId") Long bookId) { + return favoriteService.addFavorite(userId, bookId); + } + + @DeleteMapping("/user/{userId}/books/{bookId}") + public boolean removeFavorite( + @PathVariable(name = "userId") Long userId, + @PathVariable(name = "bookId") Long bookId) { + return favoriteService.removeFavorite(userId, bookId); + } + + @GetMapping("/user/{userId}/books") + public List getUserFavorites(@PathVariable(name = "userId") Long userId) { + return favoriteService.getUserFavorities(userId).stream().map(this::toBookDto).toList(); + } + + @GetMapping("/book/{bookId}/users/number") + public int getBookSubscribersNumber(@PathVariable(name = "bookId") Long bookId) { + return favoriteService.getBookSubscribersNumber(bookId); + } +} diff --git a/SpringApp/library/src/main/java/com/ip/library/favorites/service/FavoriteService.java b/SpringApp/library/src/main/java/com/ip/library/favorites/service/FavoriteService.java new file mode 100644 index 0000000..09682be --- /dev/null +++ b/SpringApp/library/src/main/java/com/ip/library/favorites/service/FavoriteService.java @@ -0,0 +1,47 @@ +package com.ip.library.favorites.service; + +import java.util.Set; + +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import com.ip.library.books.model.BookEntity; +import com.ip.library.books.service.BookService; +import com.ip.library.users.model.UserEntity; +import com.ip.library.users.service.UserService; +@Service +public class FavoriteService { + BookService bookService; + UserService userService; + + public FavoriteService (BookService bookService, UserService userService) { + this.bookService = bookService; + this.userService = userService; + } + + @Transactional + public boolean addFavorite(long userId, long bookId) { + final UserEntity existsUser = userService.get(userId); + final BookEntity book = bookService.get(bookId); + existsUser.addBook(book); + return true; + } + + @Transactional + public boolean removeFavorite(long userId, long bookId) { + final UserEntity existsUser = userService.get(userId); + final BookEntity book = bookService.get(bookId); + existsUser.removeBook(book); + return true; + } + + @Transactional(readOnly = true) + public Set getUserFavorities (long userId) { + return userService.get(userId).getBooks(); + } + + @Transactional(readOnly = true) + public int getBookSubscribersNumber(long bookId) { + return bookService.get(bookId).getUsers().size(); + } +} diff --git a/SpringApp/library/src/main/java/com/ip/library/users/api/UserController.java b/SpringApp/library/src/main/java/com/ip/library/users/api/UserController.java index 6da222c..978779b 100644 --- a/SpringApp/library/src/main/java/com/ip/library/users/api/UserController.java +++ b/SpringApp/library/src/main/java/com/ip/library/users/api/UserController.java @@ -62,18 +62,8 @@ public class UserController { return toDto(userService.delete(id)); } - @PutMapping("password/{id}") + @PutMapping("/password/{id}") public UserDto changePassword(@PathVariable(name = "id") Long id, @RequestBody String newPassword) { return toDto(userService.changePassword(id, newPassword)); } - - @GetMapping("{id}/books/{bookId}") - public boolean addBook(@PathVariable(name = "id") Long id, @PathVariable(name = "bookId") Long bookId) { - return userService.addBook(id, bookId); - } - - @DeleteMapping("{id}/books/{bookId}") - public boolean removeBook(@PathVariable(name = "id") Long id, @PathVariable(name = "bookId") Long bookId) { - return userService.removeBook(id, bookId); - } } diff --git a/SpringApp/library/src/main/java/com/ip/library/users/model/UserEntity.java b/SpringApp/library/src/main/java/com/ip/library/users/model/UserEntity.java index 69fc764..6886caa 100644 --- a/SpringApp/library/src/main/java/com/ip/library/users/model/UserEntity.java +++ b/SpringApp/library/src/main/java/com/ip/library/users/model/UserEntity.java @@ -7,8 +7,14 @@ import java.util.Set; import com.ip.library.books.model.BookEntity; import com.ip.library.core.model.BaseEntity; +import jakarta.persistence.CascadeType; import jakarta.persistence.Column; import jakarta.persistence.Entity; +import jakarta.persistence.FetchType; +import jakarta.persistence.JoinColumn; +import jakarta.persistence.JoinTable; +import jakarta.persistence.ManyToMany; +import jakarta.persistence.OrderBy; import jakarta.persistence.Table; @Entity @@ -20,6 +26,13 @@ public class UserEntity extends BaseEntity { private String password; @Column(nullable = false, unique = false, length = 20) private String role = "user"; + @ManyToMany(cascade = { CascadeType.ALL }, fetch = FetchType.EAGER) + @JoinTable( + name = "favorities", + joinColumns = { @JoinColumn(name = "userId", nullable = false) }, + inverseJoinColumns = { @JoinColumn(name = "bookId", nullable = false) } + ) + @OrderBy("id ASC") private Set books = new HashSet<>(); public UserEntity() { @@ -63,6 +76,22 @@ public class UserEntity extends BaseEntity { this.books = books; } + public BookEntity addBook(BookEntity book) { + books.add(book); + if (!book.getUsers().contains(this)) { + book.getUsers().add(this); + } + return book; + } + + public BookEntity removeBook(BookEntity book) { + books.remove(book); + if (book.getUsers().contains(this)) { + book.getUsers().remove(this); + } + return book; + } + @Override public int hashCode() { return Objects.hash(id, login, password, role); diff --git a/SpringApp/library/src/main/java/com/ip/library/users/service/UserService.java b/SpringApp/library/src/main/java/com/ip/library/users/service/UserService.java index 9280612..0818d36 100644 --- a/SpringApp/library/src/main/java/com/ip/library/users/service/UserService.java +++ b/SpringApp/library/src/main/java/com/ip/library/users/service/UserService.java @@ -6,8 +6,6 @@ import java.util.stream.StreamSupport; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; -import com.ip.library.books.model.BookEntity; -import com.ip.library.books.service.BookService; import com.ip.library.core.error.NotFoundException; import com.ip.library.users.model.UserEntity; import com.ip.library.users.repository.UserRepository; @@ -15,11 +13,9 @@ import com.ip.library.users.repository.UserRepository; @Service public class UserService { private final UserRepository repository; - private final BookService bookService; - public UserService(UserRepository repository, BookService bookService) { + public UserService(UserRepository repository) { this.repository = repository; - this.bookService = bookService; } private void checkLoginUniqueness(String name){ @@ -82,18 +78,4 @@ public class UserService { existsEntity.setPassword(newPassword); return repository.save(existsEntity); } - - @Transactional - public boolean addBook(long id, long bookId) { - final UserEntity existsEntity = get(id); - final BookEntity book = bookService.get(bookId); - return existsEntity.getBooks().add(book); - } - - @Transactional - public boolean removeBook(long id, long bookId) { - final UserEntity existsEntity = get(id); - final BookEntity book = bookService.get(bookId); - return existsEntity.getBooks().remove(book); - } } diff --git a/SpringApp/library/src/test/java/com/ip/library/BooksTests.java b/SpringApp/library/src/test/java/com/ip/library/BooksTests.java index f3addf7..e50f654 100644 --- a/SpringApp/library/src/test/java/com/ip/library/BooksTests.java +++ b/SpringApp/library/src/test/java/com/ip/library/BooksTests.java @@ -52,6 +52,7 @@ class BooksTests { Assertions.assertEquals("book3", book.getName()); Assertions.assertEquals(type, book.getType()); Assertions.assertEquals(author, book.getAuthor()); + Assertions.assertEquals(0, book.getUsers().size()); } @Test diff --git a/SpringApp/library/src/test/java/com/ip/library/FavoritesTests.java b/SpringApp/library/src/test/java/com/ip/library/FavoritesTests.java new file mode 100644 index 0000000..11a8bb6 --- /dev/null +++ b/SpringApp/library/src/test/java/com/ip/library/FavoritesTests.java @@ -0,0 +1,82 @@ +package com.ip.library; + +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; + +import com.ip.library.authors.model.AuthorEntity; +import com.ip.library.authors.service.AuthorService; +import com.ip.library.books.model.BookEntity; +import com.ip.library.books.service.BookService; +import com.ip.library.favorites.service.FavoriteService; +import com.ip.library.types.model.TypeEntity; +import com.ip.library.types.service.TypeService; +import com.ip.library.users.model.UserEntity; +import com.ip.library.users.service.UserService; + +@SpringBootTest +class FavoritesTests { + @Autowired + private FavoriteService favorityService; + @Autowired + private BookService bookService; + @Autowired + private UserService userService; + @Autowired + private TypeService typeService; + @Autowired + private AuthorService authorService; + private UserEntity user; + private BookEntity book1; + private BookEntity book2; + + @AfterEach + void removeData() { + bookService.getAll().forEach(item -> bookService.delete(item.getId())); + authorService.getAll().forEach(item -> authorService.delete(item.getId())); + typeService.getAll().forEach(item -> typeService.delete(item.getId())); + userService.getAll().forEach(item -> userService.delete(item.getId())); + } + + @BeforeEach + void createData() { + removeData(); + TypeEntity type = typeService.create(new TypeEntity("type1")); + AuthorEntity author = authorService.create(new AuthorEntity("author1")); + book1 = bookService.create(new BookEntity("book1", type, author)); + book2 = bookService.create(new BookEntity("book2", type, author)); + userService.create(new UserEntity("user1", "123")); + userService.create(new UserEntity("user2", "456")); + user = userService.create(new UserEntity("user3", "aqw2sed45")); + } + + @Test + void addAndRemoveTest() { + Assertions.assertEquals(0, user.getBooks().size()); + Assertions.assertEquals(0, book1.getUsers().size()); + Assertions.assertEquals(0, book2.getUsers().size()); + favorityService.addFavorite(user.getId(), book1.getId()); + user = userService.get(user.getId()); + book1 = bookService.get(book1.getId()); + Assertions.assertEquals(1, user.getBooks().size()); + Assertions.assertEquals(1, book1.getUsers().size()); + favorityService.addFavorite(user.getId(), book2.getId()); + user = userService.get(user.getId()); + book2 = bookService.get(book2.getId()); + Assertions.assertEquals(2, user.getBooks().size()); + Assertions.assertEquals(1, book2.getUsers().size()); + favorityService.removeFavorite(user.getId(), book1.getId()); + user = userService.get(user.getId()); + book1 = bookService.get(book1.getId()); + Assertions.assertEquals(1, user.getBooks().size()); + Assertions.assertEquals(0, book1.getUsers().size()); + favorityService.removeFavorite(user.getId(), book2.getId()); + user = userService.get(user.getId()); + book2 = bookService.get(book2.getId()); + Assertions.assertEquals(0, user.getBooks().size()); + Assertions.assertEquals(0, book2.getUsers().size()); + } +} diff --git a/SpringApp/library/src/test/java/com/ip/library/UsersTests.java b/SpringApp/library/src/test/java/com/ip/library/UsersTests.java index a648407..3feb106 100644 --- a/SpringApp/library/src/test/java/com/ip/library/UsersTests.java +++ b/SpringApp/library/src/test/java/com/ip/library/UsersTests.java @@ -7,45 +7,24 @@ import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; -import com.ip.library.authors.model.AuthorEntity; -import com.ip.library.authors.service.AuthorService; -import com.ip.library.books.model.BookEntity; -import com.ip.library.books.service.BookService; import com.ip.library.core.error.NotFoundException; -import com.ip.library.types.model.TypeEntity; -import com.ip.library.types.service.TypeService; import com.ip.library.users.model.UserEntity; import com.ip.library.users.service.UserService; @SpringBootTest class UsersTests { - @Autowired - private BookService bookService; - @Autowired - private TypeService typeService; - @Autowired - private AuthorService authorService; @Autowired private UserService userService; private UserEntity user; - private BookEntity book1; - private BookEntity book2; @AfterEach void removeData() { - authorService.getAll().forEach(item -> authorService.delete(item.getId())); - bookService.getAll().forEach(item -> bookService.delete(item.getId())); - typeService.getAll().forEach(item -> typeService.delete(item.getId())); userService.getAll().forEach(item -> userService.delete(item.getId())); } @BeforeEach void createData() { removeData(); - var type = typeService.create(new TypeEntity("type1")); - var author = authorService.create(new AuthorEntity("author1")); - book1 = bookService.create(new BookEntity("book1", type, author)); - book2 = bookService.create(new BookEntity("book2", type, author)); userService.create(new UserEntity("user1", "123")); userService.create(new UserEntity("user2", "456")); user = userService.create(new UserEntity("user3", "aqw2sed45")); @@ -93,30 +72,16 @@ class UsersTests { @Test void changePasswordTest() { String newPassword = user.getPassword() + "TEST"; - userService.changePassword(user.getId(), newPassword); + user = userService.changePassword(user.getId(), newPassword); Assertions.assertEquals(newPassword, user.getPassword()); } @Test void changeRoleTest() { Assertions.assertEquals("user", user.getRole()); - userService.giveAdminRole(user.getId()); + user = userService.giveAdminRole(user.getId()); Assertions.assertEquals("admin", user.getRole()); - userService.giveUserRole(user.getId()); + user = userService.giveUserRole(user.getId()); Assertions.assertEquals("user", user.getRole()); } - - @Test - void BooksTest() { - Assertions.assertEquals(0, user.getBooks().size()); - userService.addBook(user.getId(), book1.getId()); - Assertions.assertEquals(1, user.getBooks().size()); - userService.addBook(user.getId(), book2.getId()); - Assertions.assertEquals(2, user.getBooks().size()); - Assertions.assertEquals(2, user.getBooks().size()); - userService.removeBook(user.getId(), book1.getId()); - Assertions.assertEquals(1, user.getBooks().size()); - userService.removeBook(user.getId(), book2.getId()); - Assertions.assertEquals(0, user.getBooks().size()); - } } -- 2.25.1 From 03b6da09d54131c2f492ba2c026b57176854b16f Mon Sep 17 00:00:00 2001 From: Zakharov_Rostislav Date: Mon, 15 Apr 2024 19:56:09 +0400 Subject: [PATCH 05/21] lab-3 minor change in build --- SpringApp/library/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SpringApp/library/build.gradle b/SpringApp/library/build.gradle index 6cb9492..dd32415 100644 --- a/SpringApp/library/build.gradle +++ b/SpringApp/library/build.gradle @@ -1,6 +1,6 @@ plugins { id 'java' - id 'org.springframework.boot' version '3.2.2' + id 'org.springframework.boot' version '3.2.4' id 'io.spring.dependency-management' version '1.1.4' } -- 2.25.1 From c71d75685b2f5b2c53ee80d073dbac69515a867c Mon Sep 17 00:00:00 2001 From: Zakharov_Rostislav Date: Mon, 15 Apr 2024 22:18:14 +0400 Subject: [PATCH 06/21] lab-3 adding book and users pagination --- .../ip/library/books/api/BookController.java | 8 +- .../books/repository/BookRepository.java | 9 +- .../ip/library/books/service/BookService.java | 20 +++- .../java/com/ip/library/core/api/PageDto.java | 97 +++++++++++++++++++ .../ip/library/core/api/PageDtoMapper.java | 24 +++++ .../library/core/configuration/Constants.java | 5 +- .../ip/library/users/api/UserController.java | 11 ++- .../users/repository/UserRepository.java | 5 +- .../ip/library/users/service/UserService.java | 7 ++ 9 files changed, 173 insertions(+), 13 deletions(-) create mode 100644 SpringApp/library/src/main/java/com/ip/library/core/api/PageDto.java create mode 100644 SpringApp/library/src/main/java/com/ip/library/core/api/PageDtoMapper.java diff --git a/SpringApp/library/src/main/java/com/ip/library/books/api/BookController.java b/SpringApp/library/src/main/java/com/ip/library/books/api/BookController.java index 9aea2bd..80938c9 100644 --- a/SpringApp/library/src/main/java/com/ip/library/books/api/BookController.java +++ b/SpringApp/library/src/main/java/com/ip/library/books/api/BookController.java @@ -50,9 +50,11 @@ public class BookController { @GetMapping public List getAll( - @RequestParam(name = "typeId", defaultValue = "0") Long typeId, - @RequestParam(name = "authorId", defaultValue = "0") Long authorId) { - return itemService.getAllbyFilter(typeId, authorId).stream().map(this::toDto).toList(); + @RequestParam(name = "typeId", defaultValue = "0") Long typeId, + @RequestParam(name = "authorId", defaultValue = "0") Long authorId, + @RequestParam(name = "page", defaultValue = "0") int page, + @RequestParam(name = "size", defaultValue = Constants.DEFAULT_PAGE_SIZE) int size) { + return itemService.getAll(typeId, authorId).stream().map(this::toDto).toList(); } @GetMapping("/{id}") diff --git a/SpringApp/library/src/main/java/com/ip/library/books/repository/BookRepository.java b/SpringApp/library/src/main/java/com/ip/library/books/repository/BookRepository.java index ef63859..7a8768f 100644 --- a/SpringApp/library/src/main/java/com/ip/library/books/repository/BookRepository.java +++ b/SpringApp/library/src/main/java/com/ip/library/books/repository/BookRepository.java @@ -3,13 +3,20 @@ package com.ip.library.books.repository; import java.util.List; import java.util.Optional; +import org.springframework.data.domain.Pageable; import org.springframework.data.repository.CrudRepository; +import org.springframework.data.repository.PagingAndSortingRepository; import com.ip.library.books.model.BookEntity; -public interface BookRepository extends CrudRepository { +public interface BookRepository extends + CrudRepository, + PagingAndSortingRepository { Optional findByNameIgnoreCase(String name); List findByTypeId(long typeId); + List findByTypeId(long typeId, Pageable pageable); List findByAuthorId(long authorId); + List findByAuthorId(long authorId, Pageable pageable); List findByTypeIdAndAuthorId(long typeId, long authorId); + List findByTypeIdAndAuthorId(long typeId, long authorId, Pageable pageable); } diff --git a/SpringApp/library/src/main/java/com/ip/library/books/service/BookService.java b/SpringApp/library/src/main/java/com/ip/library/books/service/BookService.java index 18e8f2e..a658788 100644 --- a/SpringApp/library/src/main/java/com/ip/library/books/service/BookService.java +++ b/SpringApp/library/src/main/java/com/ip/library/books/service/BookService.java @@ -3,6 +3,7 @@ package com.ip.library.books.service; import java.util.List; import java.util.stream.StreamSupport; +import org.springframework.data.domain.PageRequest; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -27,12 +28,12 @@ public class BookService { } @Transactional(readOnly = true) - public List getAll() { + public List getAll(){ return StreamSupport.stream(repository.findAll().spliterator(), false).toList(); } @Transactional(readOnly = true) - public List getAllbyFilter(long typeId, long authorId) { + public List getAll(long typeId, long authorId) { if (typeId <= 0L && authorId <= 0L) { return getAll(); } @@ -45,6 +46,21 @@ public class BookService { return repository.findByTypeIdAndAuthorId(typeId, authorId); } + @Transactional(readOnly = true) + public List getAll(long typeId, long authorId, int page, int size) { + PageRequest pageRequest = PageRequest.of(page, size); + if (typeId <= 0L && authorId <= 0L) { + return StreamSupport.stream(repository.findAll(pageRequest).spliterator(), false).toList(); + } + if (typeId <= 0L){ + return repository.findByAuthorId(authorId, pageRequest); + } + if (authorId <= 0L){ + return repository.findByTypeId(typeId, pageRequest); + } + return repository.findByTypeIdAndAuthorId(typeId, authorId, pageRequest); + } + @Transactional(readOnly = true) public BookEntity get(long id) { return repository.findById(id) diff --git a/SpringApp/library/src/main/java/com/ip/library/core/api/PageDto.java b/SpringApp/library/src/main/java/com/ip/library/core/api/PageDto.java new file mode 100644 index 0000000..1de2fe4 --- /dev/null +++ b/SpringApp/library/src/main/java/com/ip/library/core/api/PageDto.java @@ -0,0 +1,97 @@ +package com.ip.library.core.api; + +import java.util.ArrayList; +import java.util.List; + +public class PageDto { + private List items = new ArrayList<>(); + private int itemsCount; + private int currentPage; + private int currentSize; + private int totalPages; + private long totalItems; + private boolean isFirst; + private boolean isLast; + private boolean hasNext; + private boolean hasPrevious; + + public List getItems() { + return items; + } + + public void setItems(List items) { + this.items = items; + } + + public int getItemsCount() { + return itemsCount; + } + + public void setItemsCount(int itemsCount) { + this.itemsCount = itemsCount; + } + + public int getCurrentPage() { + return currentPage; + } + + public void setCurrentPage(int currentPage) { + this.currentPage = currentPage; + } + + public int getCurrentSize() { + return currentSize; + } + + public void setCurrentSize(int currentSize) { + this.currentSize = currentSize; + } + + public int getTotalPages() { + return totalPages; + } + + public void setTotalPages(int totalPages) { + this.totalPages = totalPages; + } + + public long getTotalItems() { + return totalItems; + } + + public void setTotalItems(long totalItems) { + this.totalItems = totalItems; + } + + public boolean isFirst() { + return isFirst; + } + + public void setFirst(boolean isFirst) { + this.isFirst = isFirst; + } + + public boolean isLast() { + return isLast; + } + + public void setLast(boolean isLast) { + this.isLast = isLast; + } + + public boolean isHasNext() { + return hasNext; + } + + public void setHasNext(boolean hasNext) { + this.hasNext = hasNext; + } + + public boolean isHasPrevious() { + return hasPrevious; + } + + public void setHasPrevious(boolean hasPrevious) { + this.hasPrevious = hasPrevious; + } +} diff --git a/SpringApp/library/src/main/java/com/ip/library/core/api/PageDtoMapper.java b/SpringApp/library/src/main/java/com/ip/library/core/api/PageDtoMapper.java new file mode 100644 index 0000000..71ce537 --- /dev/null +++ b/SpringApp/library/src/main/java/com/ip/library/core/api/PageDtoMapper.java @@ -0,0 +1,24 @@ +package com.ip.library.core.api; + +import java.util.function.Function; + +import org.springframework.data.domain.Page; + +public class PageDtoMapper { + private PageDtoMapper() {} + + public static PageDto toDto(Page page, Function mapper) { + final PageDto dto = new PageDto<>(); + dto.setItems(page.getContent().stream().map(mapper::apply).toList()); + dto.setItemsCount(page.getNumberOfElements()); + dto.setCurrentPage(page.getNumber()); + dto.setCurrentSize(page.getSize()); + dto.setTotalPages(page.getTotalPages()); + dto.setTotalItems(page.getTotalElements()); + dto.setFirst(page.isFirst()); + dto.setLast(page.isLast()); + dto.setHasNext(page.hasNext()); + dto.setHasPrevious(page.hasPrevious()); + return dto; + } +} diff --git a/SpringApp/library/src/main/java/com/ip/library/core/configuration/Constants.java b/SpringApp/library/src/main/java/com/ip/library/core/configuration/Constants.java index 198d3a6..f5eb422 100644 --- a/SpringApp/library/src/main/java/com/ip/library/core/configuration/Constants.java +++ b/SpringApp/library/src/main/java/com/ip/library/core/configuration/Constants.java @@ -5,6 +5,7 @@ public class Constants { public static final String API_URL = "/api/1.0"; - private Constants() { - } + public static final String DEFAULT_PAGE_SIZE = "5"; + + private Constants() {} } diff --git a/SpringApp/library/src/main/java/com/ip/library/users/api/UserController.java b/SpringApp/library/src/main/java/com/ip/library/users/api/UserController.java index 978779b..62dc82c 100644 --- a/SpringApp/library/src/main/java/com/ip/library/users/api/UserController.java +++ b/SpringApp/library/src/main/java/com/ip/library/users/api/UserController.java @@ -1,7 +1,5 @@ package com.ip.library.users.api; -import java.util.List; - import org.modelmapper.ModelMapper; import org.springframework.web.bind.annotation.DeleteMapping; import org.springframework.web.bind.annotation.GetMapping; @@ -10,8 +8,11 @@ import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.PutMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; +import com.ip.library.core.api.PageDto; +import com.ip.library.core.api.PageDtoMapper; import com.ip.library.core.configuration.Constants; import com.ip.library.users.model.UserEntity; import com.ip.library.users.service.UserService; @@ -38,8 +39,10 @@ public class UserController { } @GetMapping - public List getAll() { - return userService.getAll().stream().map(this::toDto).toList(); + public PageDto getAll( + @RequestParam(name = "page", defaultValue = "0") int page, + @RequestParam(name = "size", defaultValue = Constants.DEFAULT_PAGE_SIZE) int size) { + return PageDtoMapper.toDto(userService.getAll(page, size), this::toDto); } @GetMapping("/{id}") diff --git a/SpringApp/library/src/main/java/com/ip/library/users/repository/UserRepository.java b/SpringApp/library/src/main/java/com/ip/library/users/repository/UserRepository.java index d1f4470..73a6bc1 100644 --- a/SpringApp/library/src/main/java/com/ip/library/users/repository/UserRepository.java +++ b/SpringApp/library/src/main/java/com/ip/library/users/repository/UserRepository.java @@ -3,9 +3,12 @@ package com.ip.library.users.repository; import java.util.Optional; import org.springframework.data.repository.CrudRepository; +import org.springframework.data.repository.PagingAndSortingRepository; import com.ip.library.users.model.UserEntity; -public interface UserRepository extends CrudRepository { +public interface UserRepository extends + CrudRepository, + PagingAndSortingRepository { Optional findByLoginIgnoreCase(String login); } diff --git a/SpringApp/library/src/main/java/com/ip/library/users/service/UserService.java b/SpringApp/library/src/main/java/com/ip/library/users/service/UserService.java index 0818d36..7ea2993 100644 --- a/SpringApp/library/src/main/java/com/ip/library/users/service/UserService.java +++ b/SpringApp/library/src/main/java/com/ip/library/users/service/UserService.java @@ -3,6 +3,8 @@ package com.ip.library.users.service; import java.util.List; import java.util.stream.StreamSupport; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.PageRequest; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -31,6 +33,11 @@ public class UserService { return StreamSupport.stream(repository.findAll().spliterator(), false).toList(); } + @Transactional(readOnly = true) + public Page getAll(int page, int size) { + return repository.findAll(PageRequest.of(page, size)); + } + @Transactional(readOnly = true) public UserEntity get(long id) { return repository.findById(id) -- 2.25.1 From 63d63d3b397c4192d72f5b323865c1bc10cef6d9 Mon Sep 17 00:00:00 2001 From: Zakharov_Rostislav Date: Wed, 17 Apr 2024 14:27:47 +0400 Subject: [PATCH 07/21] lab-3 add consyraints testing + some minor fixes --- .../com/ip/library/LibraryApplication.java | 55 +++++++++++++------ .../ip/library/books/api/BookController.java | 4 +- .../ip/library/users/model/UserEntity.java | 4 ++ .../java/com/ip/library/AuthorsTests.java | 25 +++++++++ .../test/java/com/ip/library/BooksTests.java | 49 +++++++++++++++++ .../test/java/com/ip/library/TypesTests.java | 25 +++++++++ .../test/java/com/ip/library/UsersTests.java | 37 +++++++++++++ 7 files changed, 179 insertions(+), 20 deletions(-) diff --git a/SpringApp/library/src/main/java/com/ip/library/LibraryApplication.java b/SpringApp/library/src/main/java/com/ip/library/LibraryApplication.java index fe1bcc5..0c06483 100644 --- a/SpringApp/library/src/main/java/com/ip/library/LibraryApplication.java +++ b/SpringApp/library/src/main/java/com/ip/library/LibraryApplication.java @@ -41,26 +41,45 @@ public class LibraryApplication implements CommandLineRunner { @Override public void run(String... args) throws Exception { - if (args.length > 0 && args[0].equals("--populate")) { - log.info("Create default types values"); - final var type1 = typeService.create(new TypeEntity("type1")); - final var type2 = typeService.create(new TypeEntity("type2")); + // if (args.length > 0 && args[0].equals("--populate")) { + // log.info("Create default types values"); + // final var type1 = typeService.create(new TypeEntity("type1")); + // final var type2 = typeService.create(new TypeEntity("type2")); - log.info("Create default authors values"); - final var author1 = authorService.create(new AuthorEntity("author1")); - final var author2 = authorService.create(new AuthorEntity("author2")); + // log.info("Create default authors values"); + // final var author1 = authorService.create(new AuthorEntity("author1")); + // final var author2 = authorService.create(new AuthorEntity("author2")); - log.info("Create default books values"); - final var book1 = bookService.create(new BookEntity("book1", type1, author1)); - final var book2 = bookService.create(new BookEntity("book2", type1, author2)); - final var book3 = bookService.create(new BookEntity("book3", type2, author1)); - final var book4 = bookService.create(new BookEntity("book4", type2, author2)); + // log.info("Create default books values"); + // final var book1 = bookService.create(new BookEntity("book1", type1, author1)); + // final var book2 = bookService.create(new BookEntity("book2", type1, author2)); + // final var book3 = bookService.create(new BookEntity("book3", type2, author1)); + // final var book4 = bookService.create(new BookEntity("book4", type2, author2)); - log.info("Create default users values"); - final var user1 = userService.create(new UserEntity("user1", "123")); - final var user2 = userService.create(new UserEntity("user2", "123")); - final var admin1 = userService.create(new UserEntity("admin1", "123")); - userService.giveAdminRole(admin1.getId()); - } + // log.info("Create default users values"); + // final var user1 = userService.create(new UserEntity("user1", "123")); + // final var user2 = userService.create(new UserEntity("user2", "123")); + // final var admin1 = userService.create(new UserEntity("admin1", "123")); + // userService.giveAdminRole(admin1.getId()); + // } + log.info("Create default types values"); + final var type1 = typeService.create(new TypeEntity("type1")); + final var type2 = typeService.create(new TypeEntity("type2")); + + log.info("Create default authors values"); + final var author1 = authorService.create(new AuthorEntity("author1")); + final var author2 = authorService.create(new AuthorEntity("author2")); + + log.info("Create default books values"); + final var book1 = bookService.create(new BookEntity("book1", type1, author1)); + final var book2 = bookService.create(new BookEntity("book2", type1, author2)); + final var book3 = bookService.create(new BookEntity("book3", type2, author1)); + final var book4 = bookService.create(new BookEntity("book4", type2, author2)); + + log.info("Create default users values"); + final var user1 = userService.create(new UserEntity("user1", "123")); + final var user2 = userService.create(new UserEntity("user2", "123")); + final var admin1 = userService.create(new UserEntity("admin1", "123")); + userService.giveAdminRole(admin1.getId()); } } diff --git a/SpringApp/library/src/main/java/com/ip/library/books/api/BookController.java b/SpringApp/library/src/main/java/com/ip/library/books/api/BookController.java index 80938c9..34a278c 100644 --- a/SpringApp/library/src/main/java/com/ip/library/books/api/BookController.java +++ b/SpringApp/library/src/main/java/com/ip/library/books/api/BookController.java @@ -50,8 +50,8 @@ public class BookController { @GetMapping public List getAll( - @RequestParam(name = "typeId", defaultValue = "0") Long typeId, - @RequestParam(name = "authorId", defaultValue = "0") Long authorId, + @RequestParam(name = "typeId", defaultValue = "-1") Long typeId, + @RequestParam(name = "authorId", defaultValue = "-1") Long authorId, @RequestParam(name = "page", defaultValue = "0") int page, @RequestParam(name = "size", defaultValue = Constants.DEFAULT_PAGE_SIZE) int size) { return itemService.getAll(typeId, authorId).stream().map(this::toDto).toList(); diff --git a/SpringApp/library/src/main/java/com/ip/library/users/model/UserEntity.java b/SpringApp/library/src/main/java/com/ip/library/users/model/UserEntity.java index 6886caa..ef2e729 100644 --- a/SpringApp/library/src/main/java/com/ip/library/users/model/UserEntity.java +++ b/SpringApp/library/src/main/java/com/ip/library/users/model/UserEntity.java @@ -44,6 +44,10 @@ public class UserEntity extends BaseEntity { this.password = password; } + public UserEntity(String login) { + this.login = login; + } + public String getLogin() { return login; } diff --git a/SpringApp/library/src/test/java/com/ip/library/AuthorsTests.java b/SpringApp/library/src/test/java/com/ip/library/AuthorsTests.java index 014b62d..6b24ede 100644 --- a/SpringApp/library/src/test/java/com/ip/library/AuthorsTests.java +++ b/SpringApp/library/src/test/java/com/ip/library/AuthorsTests.java @@ -6,6 +6,7 @@ import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.dao.DataIntegrityViolationException; import com.ip.library.core.error.NotFoundException; import com.ip.library.authors.model.AuthorEntity; @@ -60,4 +61,28 @@ class AuthorsTests { Assertions.assertEquals(3, authorService.getAll().size()); Assertions.assertNotEquals(entity.getId(), newEntity.getId()); } + + @Test + void nullNameTest() { + Assertions.assertThrows( + DataIntegrityViolationException.class, + () -> authorService.create(new AuthorEntity(null)) + ); + Assertions.assertThrows( + DataIntegrityViolationException.class, + () -> authorService.update(entity.getId(), new AuthorEntity(null)) + ); + } + + @Test + void uniqueNameTest() { + Assertions.assertThrows( + IllegalArgumentException.class, + () -> authorService.create(new AuthorEntity(entity.getName())) + ); + Assertions.assertThrows( + IllegalArgumentException.class, + () -> authorService.update(entity.getId(), new AuthorEntity(entity.getName())) + ); + } } diff --git a/SpringApp/library/src/test/java/com/ip/library/BooksTests.java b/SpringApp/library/src/test/java/com/ip/library/BooksTests.java index e50f654..48df6fe 100644 --- a/SpringApp/library/src/test/java/com/ip/library/BooksTests.java +++ b/SpringApp/library/src/test/java/com/ip/library/BooksTests.java @@ -6,6 +6,7 @@ import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.BeforeEach; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.dao.DataIntegrityViolationException; import com.ip.library.core.error.NotFoundException; import com.ip.library.types.model.TypeEntity; @@ -85,4 +86,52 @@ class BooksTests { Assertions.assertEquals(3, bookService.getAll().size()); Assertions.assertNotEquals(book.getId(), newEntity.getId()); } + + @Test + void nullNameTest() { + Assertions.assertThrows( + DataIntegrityViolationException.class, + () -> bookService.create(new BookEntity(null, book.getType(), book.getAuthor())) + ); + Assertions.assertThrows( + DataIntegrityViolationException.class, + () -> bookService.update(book.getId(), new BookEntity(null, book.getType(), book.getAuthor())) + ); + } + + @Test + void nullTypeTest() { + Assertions.assertThrows( + DataIntegrityViolationException.class, + () -> bookService.create(new BookEntity(book.getName() + "TEST", null, book.getAuthor())) + ); + Assertions.assertThrows( + DataIntegrityViolationException.class, + () -> bookService.update(book.getId(), new BookEntity(book.getName() + "TEST", null, book.getAuthor())) + ); + } + + @Test + void nullAuthorTest() { + Assertions.assertThrows( + DataIntegrityViolationException.class, + () -> bookService.create(new BookEntity(book.getName() + "TEST", book.getType(), null)) + ); + Assertions.assertThrows( + DataIntegrityViolationException.class, + () -> bookService.update(book.getId(), new BookEntity(book.getName() + "TEST", book.getType(), null)) + ); + } + + @Test + void uniqueNameTest() { + Assertions.assertThrows( + IllegalArgumentException.class, + () -> bookService.create(new BookEntity(book.getName(), book.getType(), book.getAuthor())) + ); + Assertions.assertThrows( + IllegalArgumentException.class, + () -> bookService.update(book.getId(), new BookEntity(book.getName(), book.getType(), book.getAuthor())) + ); + } } diff --git a/SpringApp/library/src/test/java/com/ip/library/TypesTests.java b/SpringApp/library/src/test/java/com/ip/library/TypesTests.java index 9c0d5bb..c0dd067 100644 --- a/SpringApp/library/src/test/java/com/ip/library/TypesTests.java +++ b/SpringApp/library/src/test/java/com/ip/library/TypesTests.java @@ -6,6 +6,7 @@ import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.dao.DataIntegrityViolationException; import com.ip.library.core.error.NotFoundException; import com.ip.library.types.model.TypeEntity; @@ -62,4 +63,28 @@ class TypesTests { Assertions.assertEquals(3, typeService.getAll().size()); Assertions.assertNotEquals(entity.getId(), newEntity.getId()); } + + @Test + void nullNameTest() { + Assertions.assertThrows( + DataIntegrityViolationException.class, + () -> typeService.create(new TypeEntity(null)) + ); + Assertions.assertThrows( + DataIntegrityViolationException.class, + () -> typeService.update(entity.getId(), new TypeEntity(null)) + ); + } + + @Test + void uniqueNameTest() { + Assertions.assertThrows( + IllegalArgumentException.class, + () -> typeService.create(new TypeEntity(entity.getName())) + ); + Assertions.assertThrows( + IllegalArgumentException.class, + () -> typeService.update(entity.getId(), new TypeEntity(entity.getName())) + ); + } } diff --git a/SpringApp/library/src/test/java/com/ip/library/UsersTests.java b/SpringApp/library/src/test/java/com/ip/library/UsersTests.java index 3feb106..12a6f52 100644 --- a/SpringApp/library/src/test/java/com/ip/library/UsersTests.java +++ b/SpringApp/library/src/test/java/com/ip/library/UsersTests.java @@ -6,6 +6,7 @@ import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.dao.DataIntegrityViolationException; import com.ip.library.core.error.NotFoundException; import com.ip.library.users.model.UserEntity; @@ -84,4 +85,40 @@ class UsersTests { user = userService.giveUserRole(user.getId()); Assertions.assertEquals("user", user.getRole()); } + + @Test + void nullLoginTest() { + Assertions.assertThrows( + DataIntegrityViolationException.class, + () -> userService.create(new UserEntity(null, user.getPassword())) + ); + Assertions.assertThrows( + DataIntegrityViolationException.class, + () -> userService.update(user.getId(), new UserEntity(null)) + ); + } + + @Test + void nullPasswordTest() { + Assertions.assertThrows( + DataIntegrityViolationException.class, + () -> userService.create(new UserEntity(user.getLogin() + "TEST", null)) + ); + Assertions.assertThrows( + DataIntegrityViolationException.class, + () -> userService.changePassword(user.getId(), null) + ); + } + + @Test + void uniqueLoginTest() { + Assertions.assertThrows( + IllegalArgumentException.class, + () -> userService.create(new UserEntity(user.getLogin(), user.getPassword())) + ); + Assertions.assertThrows( + IllegalArgumentException.class, + () -> userService.update(user.getId(), new UserEntity(user.getLogin())) + ); + } } -- 2.25.1 From addf626c2e8d1855c80c5904b9b8208b7ea1d252 Mon Sep 17 00:00:00 2001 From: Zakharov_Rostislav Date: Wed, 17 Apr 2024 14:32:24 +0400 Subject: [PATCH 08/21] lab-3 some configuration --- .../main/resources/application-dev.properties | 8 ++++++++ .../resources/application-prod.properties | 9 +++++++++ .../src/main/resources/application.properties | 20 +++++++++++++++++++ 3 files changed, 37 insertions(+) create mode 100644 SpringApp/library/src/main/resources/application-dev.properties create mode 100644 SpringApp/library/src/main/resources/application-prod.properties diff --git a/SpringApp/library/src/main/resources/application-dev.properties b/SpringApp/library/src/main/resources/application-dev.properties new file mode 100644 index 0000000..4ed3960 --- /dev/null +++ b/SpringApp/library/src/main/resources/application-dev.properties @@ -0,0 +1,8 @@ +# Dev H2 JPA Settings +spring.datasource.url=jdbc:h2:file:./data +spring.datasource.username=sa +spring.datasource.password=password +spring.datasource.driver-class-name=org.h2.Driver + +# H2 console +spring.h2.console.enabled=true \ No newline at end of file diff --git a/SpringApp/library/src/main/resources/application-prod.properties b/SpringApp/library/src/main/resources/application-prod.properties new file mode 100644 index 0000000..aaf9d7d --- /dev/null +++ b/SpringApp/library/src/main/resources/application-prod.properties @@ -0,0 +1,9 @@ +# Logger settings +# Available levels are: TRACE, DEBUG, INFO, WARN, ERROR, FATAL, OFF +logging.level.com.example.demo=INFO + +# Prod PostgreSQL JPA Settings +spring.datasource.url=jdbc:postgresql://127.0.0.1:5432/demo-app +spring.datasource.username=postgres +spring.datasource.password=postgres +spring.datasource.driver-class-name=org.postgresql.Driver diff --git a/SpringApp/library/src/main/resources/application.properties b/SpringApp/library/src/main/resources/application.properties index 8b13789..8f5373c 100644 --- a/SpringApp/library/src/main/resources/application.properties +++ b/SpringApp/library/src/main/resources/application.properties @@ -1 +1,21 @@ +# Server +spring.main.banner-mode=off +server.port=8080 +# Logger settings +# Available levels are: TRACE, DEBUG, INFO, WARN, ERROR, FATAL, OFF +logging.level.com.example.demo=DEBUG + +# Set default orofile +spring.profiles.default=dev + +# Common JPA Settings +spring.jpa.hibernate.ddl-auto=validate +spring.jpa.open-in-view=false +# spring.jpa.show-sql=true +# spring.jpa.properties.hibernate.format_sql=true + +# Liquibase Settings +spring.liquibase.enabled=true +spring.liquibase.drop-first=false +spring.liquibase.change-log=classpath:db/changelog.xml \ No newline at end of file -- 2.25.1 From 7977bcc9d54523dbd8356842f1525c477f3ce6e3 Mon Sep 17 00:00:00 2001 From: Zakharov_Rostislav Date: Wed, 17 Apr 2024 14:59:46 +0400 Subject: [PATCH 09/21] lab-3 some configuring p.2 --- SpringApp/.vscode/launch.json | 2 +- .../com/ip/library/LibraryApplication.java | 55 ++++++------------- .../src/main/resources/application.properties | 2 +- 3 files changed, 20 insertions(+), 39 deletions(-) diff --git a/SpringApp/.vscode/launch.json b/SpringApp/.vscode/launch.json index 323cbac..b1e2afa 100644 --- a/SpringApp/.vscode/launch.json +++ b/SpringApp/.vscode/launch.json @@ -7,7 +7,7 @@ "cwd": "${workspaceFolder}", "mainClass": "com.ip.library.LibraryApplication", "projectName": "library", - "args": "", + "args": "--populate", "envFile": "${workspaceFolder}/.env" } ] diff --git a/SpringApp/library/src/main/java/com/ip/library/LibraryApplication.java b/SpringApp/library/src/main/java/com/ip/library/LibraryApplication.java index 0c06483..fe1bcc5 100644 --- a/SpringApp/library/src/main/java/com/ip/library/LibraryApplication.java +++ b/SpringApp/library/src/main/java/com/ip/library/LibraryApplication.java @@ -41,45 +41,26 @@ public class LibraryApplication implements CommandLineRunner { @Override public void run(String... args) throws Exception { - // if (args.length > 0 && args[0].equals("--populate")) { - // log.info("Create default types values"); - // final var type1 = typeService.create(new TypeEntity("type1")); - // final var type2 = typeService.create(new TypeEntity("type2")); + if (args.length > 0 && args[0].equals("--populate")) { + log.info("Create default types values"); + final var type1 = typeService.create(new TypeEntity("type1")); + final var type2 = typeService.create(new TypeEntity("type2")); - // log.info("Create default authors values"); - // final var author1 = authorService.create(new AuthorEntity("author1")); - // final var author2 = authorService.create(new AuthorEntity("author2")); + log.info("Create default authors values"); + final var author1 = authorService.create(new AuthorEntity("author1")); + final var author2 = authorService.create(new AuthorEntity("author2")); - // log.info("Create default books values"); - // final var book1 = bookService.create(new BookEntity("book1", type1, author1)); - // final var book2 = bookService.create(new BookEntity("book2", type1, author2)); - // final var book3 = bookService.create(new BookEntity("book3", type2, author1)); - // final var book4 = bookService.create(new BookEntity("book4", type2, author2)); + log.info("Create default books values"); + final var book1 = bookService.create(new BookEntity("book1", type1, author1)); + final var book2 = bookService.create(new BookEntity("book2", type1, author2)); + final var book3 = bookService.create(new BookEntity("book3", type2, author1)); + final var book4 = bookService.create(new BookEntity("book4", type2, author2)); - // log.info("Create default users values"); - // final var user1 = userService.create(new UserEntity("user1", "123")); - // final var user2 = userService.create(new UserEntity("user2", "123")); - // final var admin1 = userService.create(new UserEntity("admin1", "123")); - // userService.giveAdminRole(admin1.getId()); - // } - log.info("Create default types values"); - final var type1 = typeService.create(new TypeEntity("type1")); - final var type2 = typeService.create(new TypeEntity("type2")); - - log.info("Create default authors values"); - final var author1 = authorService.create(new AuthorEntity("author1")); - final var author2 = authorService.create(new AuthorEntity("author2")); - - log.info("Create default books values"); - final var book1 = bookService.create(new BookEntity("book1", type1, author1)); - final var book2 = bookService.create(new BookEntity("book2", type1, author2)); - final var book3 = bookService.create(new BookEntity("book3", type2, author1)); - final var book4 = bookService.create(new BookEntity("book4", type2, author2)); - - log.info("Create default users values"); - final var user1 = userService.create(new UserEntity("user1", "123")); - final var user2 = userService.create(new UserEntity("user2", "123")); - final var admin1 = userService.create(new UserEntity("admin1", "123")); - userService.giveAdminRole(admin1.getId()); + log.info("Create default users values"); + final var user1 = userService.create(new UserEntity("user1", "123")); + final var user2 = userService.create(new UserEntity("user2", "123")); + final var admin1 = userService.create(new UserEntity("admin1", "123")); + userService.giveAdminRole(admin1.getId()); + } } } diff --git a/SpringApp/library/src/main/resources/application.properties b/SpringApp/library/src/main/resources/application.properties index 8f5373c..5baf834 100644 --- a/SpringApp/library/src/main/resources/application.properties +++ b/SpringApp/library/src/main/resources/application.properties @@ -6,7 +6,7 @@ server.port=8080 # Available levels are: TRACE, DEBUG, INFO, WARN, ERROR, FATAL, OFF logging.level.com.example.demo=DEBUG -# Set default orofile +# Set default profile spring.profiles.default=dev # Common JPA Settings -- 2.25.1 From 8eda0b0429951c07b4f09cb54a6cdcc03b998313 Mon Sep 17 00:00:00 2001 From: Zakharov_Rostislav Date: Wed, 17 Apr 2024 15:10:16 +0400 Subject: [PATCH 10/21] lab-3 some configuring p.3 --- SpringApp/library/data.mv.db | Bin 0 -> 28672 bytes .../src/main/resources/application.properties | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) create mode 100644 SpringApp/library/data.mv.db diff --git a/SpringApp/library/data.mv.db b/SpringApp/library/data.mv.db new file mode 100644 index 0000000000000000000000000000000000000000..d9586c333e570565960073a5999ec3fc36810274 GIT binary patch literal 28672 zcmeGlOK;ogk(6ayan^aP^Vn=QyNov3#9OV(k8i4%$hH(Kwq>s*JI;22l%mMQjco;v zoQ->FQ1sSI3lwO9K7d||7Cp2D+FK8MTI`{FFWN(aUit$H6e!R`hu?z_iL~X!NmG;p z%x_43kNJkf`DVVEq326dp}pC)ACzQLHaEWEl#nQj1^fQ)_Jfk773>|y>N%YfG90Jf z);qRk7ToU6meqqskDZ-I8{KWMp1bMv?EB76$(B{ilvQPdOMfW^QVOILNGXs~Af-S` zfs_I%1yTy66i6wMQXr+kD?owy)c$`3o0x1Pj z3ZxWxu@s@xB1YZ3u>q*I$L?|DE+rO~W?eqtghv9ykYBy{37A8P_b#bvk?$pammAo)J zUv89VTR@_#Fb9;Z)n{8mtv**-56x+I zx!!Cw$}r+xeCsYej^%o&f{$UIpg{Vo)*8*$^n1e9$tUn&0H36Z0b%EaV31J9!9{P( zRgCR*GRX8WXkLT4-lTI~Y1Ed0Ai_fBPG|&r^)6i9XIen>>FY3&PmW?DFq052*S!Zi zIGHG3)4(OaV(g#5CNs;+3qF&OCvrELSCa3v?yOYyX_&-hYJ|z&2g2WfJ|>gW3oy^h&fJy8=|0HG)%Up842+XxX=a9f# z)$-bMqt>cbdVKeA~B4dC@Mc?=qWV#k?21X)qmj3CnM2?kf#hW zIwBxh1VNK3NEkm=ZZiaRQ#Xu31Vhw=nSio{bk_}Gh$J2zH*sgO<#vqY2AR3y+9HEh z%?M!I*4TBeV@M3vfv7%gL4DGvC|O83PP93IMa1d=?AMp!A+YPRDJl#G?M4E%3pB9z zK@;;zPZNV5|9LBE)vYd6Z`Ic4rL{Xt((GFGmb_YBzh$CZl_fndRF@l-+ReJRj9$+N z%go>kwoflqjR0}js8lNrPlW;%&ex#=bpkJq^<_|tW*4%TKytWLa`dYx)djUuU2e{- z>c&b1p`{8cFD%tp8lqYb28#$1ww(COU07+!z75j&bN<=H@jkfpk&lfXN4z2C6H7d= zPmt0?t6-#i2T1oIk#w__+MU~~_@Q38b8}8J*X|hdOly6mNnwn7%_V%4@lnA?6(2Qx)bWwjG%;-9V;diBeC*(( zgOBdmwzcIH?@r=kW4q%#0R$sw>SUk&?MKtAK{UPG5s{=R>JggLepeH8e64SJ_EZON zNsie6SW^hCzq;v2ZlDQhVf!D}Tz`-w06hEu9qxPF@eDVT<>Uoxw|Bq0gA@wDk_6iW z|K?wV+w5L8bdOWGe`Y4LoVPW=$ttR~yWIy!(Fh>Px`eOD%4m*23Uqjlzc6wF+K|d) zxRAz4#T+iYTHHlGlRce*od*updV3EYB;mqC=>qSJz7Ds@^^AX=o8`}qO^tA{OTmpE ztAVDqgKi>8p7)^934B2cE*!sQb+$IPag`bdq3_H5Z^zG!aO@uKg|_wZn&SVKI}7N` zCU2e?4{%E}=0rF6BH7N2W5LPlR;aK&556t@_e*+g~uH>|mYIV@$%JOegbM zb!d$dbX$*o2XtFC;OIE@(RD@rRaYN>#3-p!^;U|!-f~F2l`tj4+N}|6`_cWp{dWKM zBcB>)8Yq3btx2Q`)@><_bz25|x-EsVZcAaT+cJ1R-ImtDx-EsVZp&a#x1})AZ8M*O zZtJ}o@P_~%xxsN}7Rsj_SIux-7S5O9diE*Dt-)XRQ;z%iGmabOIBx4(P~PCUUAQ*- zl;geuf8Ot#txC+EOlUWX?1QEDf6`VY(oN065K~pVE>CT?xTqPk0_=(etn+PePrPHnvnZQb95CAZcv~AK@{&k^6meF zy@Utb|HIe`A@5s=e6g-U&;BPfJzC!u>67@jh)?qweOsyhAKI6YQ~$r`|34M-|09=) z#z0uUG#SbK|H!41hbay$a4&FNA7uYi8L4C6aww`#liOw|kdZ+!K19zsqGi-YCl&Sq6zjZQ%mpnqci0hiU-=q5{ssBIq|0nwY zfAhcZ|7Z4h$e8xOrYBoYM^Y4dz<57`3(Wo};dy}pO3ty`jtHACIag71Q8A62 z+jb${tqYu4tjGiUXz7K8#6`s(za6xT=yrPIL` zy-HWAmJL1ZUG1w39X7h3u&!9GtmkHgUw>^c@}M}g*K^7{JJud+^#Tyccz)4=;p36b zz>nkmQBAJP4_P;Rh4rkF`>6Hg7LCAYW_$oGeLc`?OE+j zr%2Nl$O%%&fb@)_M$RND+)N3dm?!ZtJ!k777&U;x34Ff0-RUlN?-fz>RMNe>C7L#& z(tkog&1d*%;R9!{#O(FLV{5a-40FI;;A2*GTi|q%?Otyy*x3@93Cx!MOZl7AS| z|E?N%lP!iv=(~D|+3^zZWRRFaQU)m*q-KzoL3#!myv>`u#v8oMtGt^*D1&6a&3Aa6 zS9l9{VO~G~mux8CB?xn2PF?w>`EvbymxG;<#FraMLXHM=(+uQ&Lr5UuB{m&7lrJ40 zPvRaTo&*i%lk_D^A2OaKgk5YriTaACn)ju<$(*%|L6pf_X?08n%`&=51UNF z8*#j#=&FWBzJ~$YApLBICYpnBgML^Hk@5=U`Gr2&;reovMiw!bB#A5nT>G%|zS0qk z9TV_aDyfQXQ|v%F9tu4o<|Ww*qbKud0!J#T3hEdH6eSZW1Vo}MA`n$iIc}N?vy)Vq zorCXFz;`M#za&C!v`mEB*cU6FY)gMB1^$~9p!xUA{~q$C2mb#yd`?b%LHYmx0oofH A)Bpeg literal 0 HcmV?d00001 diff --git a/SpringApp/library/src/main/resources/application.properties b/SpringApp/library/src/main/resources/application.properties index 5baf834..3e18e21 100644 --- a/SpringApp/library/src/main/resources/application.properties +++ b/SpringApp/library/src/main/resources/application.properties @@ -10,7 +10,7 @@ logging.level.com.example.demo=DEBUG spring.profiles.default=dev # Common JPA Settings -spring.jpa.hibernate.ddl-auto=validate +spring.jpa.hibernate.ddl-auto=create spring.jpa.open-in-view=false # spring.jpa.show-sql=true # spring.jpa.properties.hibernate.format_sql=true -- 2.25.1 From 27261af156a700652ca70f003c900cb8a0e22ef5 Mon Sep 17 00:00:00 2001 From: Zakharov_Rostislav Date: Wed, 17 Apr 2024 16:14:32 +0400 Subject: [PATCH 11/21] lab-3 add db to gitignore p.1 --- SpringApp/library/data.mv.db | Bin 28672 -> 0 bytes 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 SpringApp/library/data.mv.db diff --git a/SpringApp/library/data.mv.db b/SpringApp/library/data.mv.db deleted file mode 100644 index d9586c333e570565960073a5999ec3fc36810274..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 28672 zcmeGlOK;ogk(6ayan^aP^Vn=QyNov3#9OV(k8i4%$hH(Kwq>s*JI;22l%mMQjco;v zoQ->FQ1sSI3lwO9K7d||7Cp2D+FK8MTI`{FFWN(aUit$H6e!R`hu?z_iL~X!NmG;p z%x_43kNJkf`DVVEq326dp}pC)ACzQLHaEWEl#nQj1^fQ)_Jfk773>|y>N%YfG90Jf z);qRk7ToU6meqqskDZ-I8{KWMp1bMv?EB76$(B{ilvQPdOMfW^QVOILNGXs~Af-S` zfs_I%1yTy66i6wMQXr+kD?owy)c$`3o0x1Pj z3ZxWxu@s@xB1YZ3u>q*I$L?|DE+rO~W?eqtghv9ykYBy{37A8P_b#bvk?$pammAo)J zUv89VTR@_#Fb9;Z)n{8mtv**-56x+I zx!!Cw$}r+xeCsYej^%o&f{$UIpg{Vo)*8*$^n1e9$tUn&0H36Z0b%EaV31J9!9{P( zRgCR*GRX8WXkLT4-lTI~Y1Ed0Ai_fBPG|&r^)6i9XIen>>FY3&PmW?DFq052*S!Zi zIGHG3)4(OaV(g#5CNs;+3qF&OCvrELSCa3v?yOYyX_&-hYJ|z&2g2WfJ|>gW3oy^h&fJy8=|0HG)%Up842+XxX=a9f# z)$-bMqt>cbdVKeA~B4dC@Mc?=qWV#k?21X)qmj3CnM2?kf#hW zIwBxh1VNK3NEkm=ZZiaRQ#Xu31Vhw=nSio{bk_}Gh$J2zH*sgO<#vqY2AR3y+9HEh z%?M!I*4TBeV@M3vfv7%gL4DGvC|O83PP93IMa1d=?AMp!A+YPRDJl#G?M4E%3pB9z zK@;;zPZNV5|9LBE)vYd6Z`Ic4rL{Xt((GFGmb_YBzh$CZl_fndRF@l-+ReJRj9$+N z%go>kwoflqjR0}js8lNrPlW;%&ex#=bpkJq^<_|tW*4%TKytWLa`dYx)djUuU2e{- z>c&b1p`{8cFD%tp8lqYb28#$1ww(COU07+!z75j&bN<=H@jkfpk&lfXN4z2C6H7d= zPmt0?t6-#i2T1oIk#w__+MU~~_@Q38b8}8J*X|hdOly6mNnwn7%_V%4@lnA?6(2Qx)bWwjG%;-9V;diBeC*(( zgOBdmwzcIH?@r=kW4q%#0R$sw>SUk&?MKtAK{UPG5s{=R>JggLepeH8e64SJ_EZON zNsie6SW^hCzq;v2ZlDQhVf!D}Tz`-w06hEu9qxPF@eDVT<>Uoxw|Bq0gA@wDk_6iW z|K?wV+w5L8bdOWGe`Y4LoVPW=$ttR~yWIy!(Fh>Px`eOD%4m*23Uqjlzc6wF+K|d) zxRAz4#T+iYTHHlGlRce*od*updV3EYB;mqC=>qSJz7Ds@^^AX=o8`}qO^tA{OTmpE ztAVDqgKi>8p7)^934B2cE*!sQb+$IPag`bdq3_H5Z^zG!aO@uKg|_wZn&SVKI}7N` zCU2e?4{%E}=0rF6BH7N2W5LPlR;aK&556t@_e*+g~uH>|mYIV@$%JOegbM zb!d$dbX$*o2XtFC;OIE@(RD@rRaYN>#3-p!^;U|!-f~F2l`tj4+N}|6`_cWp{dWKM zBcB>)8Yq3btx2Q`)@><_bz25|x-EsVZcAaT+cJ1R-ImtDx-EsVZp&a#x1})AZ8M*O zZtJ}o@P_~%xxsN}7Rsj_SIux-7S5O9diE*Dt-)XRQ;z%iGmabOIBx4(P~PCUUAQ*- zl;geuf8Ot#txC+EOlUWX?1QEDf6`VY(oN065K~pVE>CT?xTqPk0_=(etn+PePrPHnvnZQb95CAZcv~AK@{&k^6meF zy@Utb|HIe`A@5s=e6g-U&;BPfJzC!u>67@jh)?qweOsyhAKI6YQ~$r`|34M-|09=) z#z0uUG#SbK|H!41hbay$a4&FNA7uYi8L4C6aww`#liOw|kdZ+!K19zsqGi-YCl&Sq6zjZQ%mpnqci0hiU-=q5{ssBIq|0nwY zfAhcZ|7Z4h$e8xOrYBoYM^Y4dz<57`3(Wo};dy}pO3ty`jtHACIag71Q8A62 z+jb${tqYu4tjGiUXz7K8#6`s(za6xT=yrPIL` zy-HWAmJL1ZUG1w39X7h3u&!9GtmkHgUw>^c@}M}g*K^7{JJud+^#Tyccz)4=;p36b zz>nkmQBAJP4_P;Rh4rkF`>6Hg7LCAYW_$oGeLc`?OE+j zr%2Nl$O%%&fb@)_M$RND+)N3dm?!ZtJ!k777&U;x34Ff0-RUlN?-fz>RMNe>C7L#& z(tkog&1d*%;R9!{#O(FLV{5a-40FI;;A2*GTi|q%?Otyy*x3@93Cx!MOZl7AS| z|E?N%lP!iv=(~D|+3^zZWRRFaQU)m*q-KzoL3#!myv>`u#v8oMtGt^*D1&6a&3Aa6 zS9l9{VO~G~mux8CB?xn2PF?w>`EvbymxG;<#FraMLXHM=(+uQ&Lr5UuB{m&7lrJ40 zPvRaTo&*i%lk_D^A2OaKgk5YriTaACn)ju<$(*%|L6pf_X?08n%`&=51UNF z8*#j#=&FWBzJ~$YApLBICYpnBgML^Hk@5=U`Gr2&;reovMiw!bB#A5nT>G%|zS0qk z9TV_aDyfQXQ|v%F9tu4o<|Ww*qbKud0!J#T3hEdH6eSZW1Vo}MA`n$iIc}N?vy)Vq zorCXFz;`M#za&C!v`mEB*cU6FY)gMB1^$~9p!xUA{~q$C2mb#yd`?b%LHYmx0oofH A)Bpeg -- 2.25.1 From 21e68a6690fa18a0e12fa024fc2e2287aa1125c7 Mon Sep 17 00:00:00 2001 From: Zakharov_Rostislav Date: Wed, 17 Apr 2024 16:16:29 +0400 Subject: [PATCH 12/21] lab-3 add db to gitignore p.2 --- .gitignore | 1 + 1 file changed, 1 insertion(+) create mode 100644 .gitignore diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..2c4a283 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +SpringApp/data.mv.db -- 2.25.1 From 264c14bba85ba1914e62e22c73355bd29ec49fdf Mon Sep 17 00:00:00 2001 From: Zakharov_Rostislav Date: Fri, 19 Apr 2024 11:17:49 +0400 Subject: [PATCH 13/21] lab-3. Additional task is done: many to many association author<->book + 3 jpql requests + some refactoring. But some errors --- .gitignore | 2 + .../com/ip/library/LibraryApplication.java | 30 ++++++- .../library/authors/api/AuthorController.java | 9 +++ .../library/authors/model/AuthorEntity.java | 27 ++++++- .../authors/repository/AuthorRepository.java | 15 +++- .../authors/service/AuthorService.java | 6 ++ .../ip/library/books/api/BookController.java | 30 ++++--- .../com/ip/library/books/api/BookDto.java | 13 +-- .../ip/library/books/model/BookEntity.java | 70 ++++++---------- .../books/repository/BookRepository.java | 13 ++- .../ip/library/books/service/BookService.java | 35 ++++---- .../favorites/api/FavoriteController.java | 56 ------------- .../favorites/model/FavoriteEntity.java | 79 +++++++++++++++++++ .../library/favorites/model/UserBookId.java | 55 +++++++++++++ .../favorites/service/FavoriteService.java | 47 ----------- .../ip/library/types/model/TypeEntity.java | 5 +- .../ip/library/users/api/UserController.java | 42 ++++++++-- .../ip/library/users/model/UserEntity.java | 50 +++++------- .../users/repository/UserRepository.java | 10 +++ .../ip/library/users/service/UserService.java | 25 +++++- .../test/java/com/ip/library/BooksTests.java | 56 ++++++------- .../java/com/ip/library/FavoritesTests.java | 49 ++++++------ .../test/java/com/ip/library/UsersTests.java | 4 +- 23 files changed, 426 insertions(+), 302 deletions(-) delete mode 100644 SpringApp/library/src/main/java/com/ip/library/favorites/api/FavoriteController.java create mode 100644 SpringApp/library/src/main/java/com/ip/library/favorites/model/FavoriteEntity.java create mode 100644 SpringApp/library/src/main/java/com/ip/library/favorites/model/UserBookId.java delete mode 100644 SpringApp/library/src/main/java/com/ip/library/favorites/service/FavoriteService.java diff --git a/.gitignore b/.gitignore index 2c4a283..a057160 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,3 @@ SpringApp/data.mv.db +SpringApp/library/data.mv.db +SpringApp/library/data.trace.db diff --git a/SpringApp/library/src/main/java/com/ip/library/LibraryApplication.java b/SpringApp/library/src/main/java/com/ip/library/LibraryApplication.java index fe1bcc5..73bcb0a 100644 --- a/SpringApp/library/src/main/java/com/ip/library/LibraryApplication.java +++ b/SpringApp/library/src/main/java/com/ip/library/LibraryApplication.java @@ -1,5 +1,10 @@ package com.ip.library; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + import org.modelmapper.internal.util.Objects; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -49,18 +54,35 @@ public class LibraryApplication implements CommandLineRunner { log.info("Create default authors values"); final var author1 = authorService.create(new AuthorEntity("author1")); final var author2 = authorService.create(new AuthorEntity("author2")); + + final List list1 = new ArrayList<>(); + final List list2 = new ArrayList<>(); + final List list3 = new ArrayList<>(); + + list1.add(author1); + list2.add(author2); + list3.add(author1); + list3.add(author2); log.info("Create default books values"); - final var book1 = bookService.create(new BookEntity("book1", type1, author1)); - final var book2 = bookService.create(new BookEntity("book2", type1, author2)); - final var book3 = bookService.create(new BookEntity("book3", type2, author1)); - final var book4 = bookService.create(new BookEntity("book4", type2, author2)); + final var book1 = bookService.create(new BookEntity("book1", type1, list1)); + final var book2 = bookService.create(new BookEntity("book2", type1, list2)); + final var book3 = bookService.create(new BookEntity("book3", type2, list3)); + final var book4 = bookService.create(new BookEntity("book4", type2)); log.info("Create default users values"); final var user1 = userService.create(new UserEntity("user1", "123")); final var user2 = userService.create(new UserEntity("user2", "123")); final var admin1 = userService.create(new UserEntity("admin1", "123")); + userService.giveAdminRole(admin1.getId()); + + userService.addFavorite(user1.getId(), book1.getId()); + userService.addFavorite(user1.getId(), book2.getId()); + userService.addFavorite(user1.getId(), book3.getId()); + userService.addFavorite(user1.getId(), book4.getId()); + userService.addFavorite(user2.getId(), book1.getId()); + userService.addFavorite(user2.getId(), book2.getId()); } } } diff --git a/SpringApp/library/src/main/java/com/ip/library/authors/api/AuthorController.java b/SpringApp/library/src/main/java/com/ip/library/authors/api/AuthorController.java index 7e9ea45..22f1a66 100644 --- a/SpringApp/library/src/main/java/com/ip/library/authors/api/AuthorController.java +++ b/SpringApp/library/src/main/java/com/ip/library/authors/api/AuthorController.java @@ -15,8 +15,11 @@ import org.springframework.web.bind.annotation.RestController; import com.ip.library.core.configuration.Constants; import com.ip.library.authors.model.AuthorEntity; import com.ip.library.authors.service.AuthorService; +import com.ip.library.books.model.BookEntity; import jakarta.validation.Valid; +import org.springframework.web.bind.annotation.RequestParam; + @RestController @RequestMapping(Constants.API_URL + "/author") @@ -61,4 +64,10 @@ public class AuthorController { public AuthorDto delete(@PathVariable(name = "id") Long id) { return toDto(authorService.delete(id)); } + + @GetMapping("/{id}/books") + public List getAuthorBooks(@PathVariable(name = "id") Long id) { + return authorService.getAuthorBooks(id); + } + } diff --git a/SpringApp/library/src/main/java/com/ip/library/authors/model/AuthorEntity.java b/SpringApp/library/src/main/java/com/ip/library/authors/model/AuthorEntity.java index 2420b69..9a96e32 100644 --- a/SpringApp/library/src/main/java/com/ip/library/authors/model/AuthorEntity.java +++ b/SpringApp/library/src/main/java/com/ip/library/authors/model/AuthorEntity.java @@ -1,11 +1,18 @@ package com.ip.library.authors.model; +import java.util.HashSet; import java.util.Objects; +import java.util.Set; +import com.ip.library.books.model.BookEntity; import com.ip.library.core.model.BaseEntity; +import jakarta.persistence.CascadeType; import jakarta.persistence.Column; import jakarta.persistence.Entity; +import jakarta.persistence.JoinColumn; +import jakarta.persistence.JoinTable; +import jakarta.persistence.ManyToMany; import jakarta.persistence.Table; @Entity @@ -13,6 +20,13 @@ import jakarta.persistence.Table; public class AuthorEntity extends BaseEntity { @Column(nullable = false, unique = true, length = 20) private String name; + @ManyToMany(cascade = { CascadeType.ALL }) + @JoinTable( + name = "authors_books", + joinColumns = { @JoinColumn(name = "author_id", nullable = false) }, + inverseJoinColumns = { @JoinColumn(name = "book_id", nullable = false) } + ) + private Set books = new HashSet<>(); public AuthorEntity() { super(); @@ -30,6 +44,14 @@ public class AuthorEntity extends BaseEntity { this.name = name; } + public Set getBooks() { + return books; + } + + public void setBooks(Set books) { + this.books = books; + } + @Override public int hashCode() { return Objects.hash(id, name); @@ -42,8 +64,9 @@ public class AuthorEntity extends BaseEntity { if (obj == null || getClass() != obj.getClass()) return false; final AuthorEntity other = (AuthorEntity) obj; - return Objects.equals(other.getId(), id) - && Objects.equals(other.getName(), name); + return + Objects.equals(other.getId(), id) + && Objects.equals(other.getName(), name); } } diff --git a/SpringApp/library/src/main/java/com/ip/library/authors/repository/AuthorRepository.java b/SpringApp/library/src/main/java/com/ip/library/authors/repository/AuthorRepository.java index 0e8e9b6..5cd00a2 100644 --- a/SpringApp/library/src/main/java/com/ip/library/authors/repository/AuthorRepository.java +++ b/SpringApp/library/src/main/java/com/ip/library/authors/repository/AuthorRepository.java @@ -1,11 +1,24 @@ package com.ip.library.authors.repository; +import java.util.List; import java.util.Optional; +import org.springframework.data.jpa.repository.Query; import org.springframework.data.repository.CrudRepository; +import org.springframework.data.repository.PagingAndSortingRepository; import com.ip.library.authors.model.AuthorEntity; +import com.ip.library.books.model.BookEntity; -public interface AuthorRepository extends CrudRepository { +public interface AuthorRepository extends + CrudRepository, + PagingAndSortingRepository { Optional findByNameIgnoreCase(String name); + @Query( + "select a.books " + + "from AuthorEntity a, BookEntity b " + + "where a.id = ?1 " + + "order by b.id" + ) + List getAuthorBooks(Long authorId); } diff --git a/SpringApp/library/src/main/java/com/ip/library/authors/service/AuthorService.java b/SpringApp/library/src/main/java/com/ip/library/authors/service/AuthorService.java index 27eee8f..a93ffcf 100644 --- a/SpringApp/library/src/main/java/com/ip/library/authors/service/AuthorService.java +++ b/SpringApp/library/src/main/java/com/ip/library/authors/service/AuthorService.java @@ -9,6 +9,7 @@ import org.springframework.transaction.annotation.Transactional; import com.ip.library.core.error.NotFoundException; import com.ip.library.authors.model.AuthorEntity; import com.ip.library.authors.repository.AuthorRepository; +import com.ip.library.books.model.BookEntity; @Service public class AuthorService { @@ -63,4 +64,9 @@ public class AuthorService { repository.delete(existsEntity); return existsEntity; } + + @Transactional + public List getAuthorBooks(long authorId) { + return repository.getAuthorBooks(authorId); + } } diff --git a/SpringApp/library/src/main/java/com/ip/library/books/api/BookController.java b/SpringApp/library/src/main/java/com/ip/library/books/api/BookController.java index 34a278c..47f959b 100644 --- a/SpringApp/library/src/main/java/com/ip/library/books/api/BookController.java +++ b/SpringApp/library/src/main/java/com/ip/library/books/api/BookController.java @@ -22,16 +22,16 @@ import com.ip.library.authors.service.AuthorService; import jakarta.validation.Valid; @RestController -@RequestMapping(Constants.API_URL + "/books") +@RequestMapping(Constants.API_URL + "/book") public class BookController { - private final BookService itemService; + private final BookService bookService; private final TypeService typeService; private final AuthorService authorService; private final ModelMapper modelMapper; public BookController(BookService itemService, TypeService typeService, AuthorService authorService, ModelMapper modelMapper) { - this.itemService = itemService; + this.bookService = itemService; this.typeService = typeService; this.authorService = authorService; this.modelMapper = modelMapper; @@ -44,36 +44,40 @@ public class BookController { private BookEntity toEntity(BookDto dto) { final BookEntity entity = modelMapper.map(dto, BookEntity.class); entity.setType(typeService.get(dto.getTypeId())); - entity.setAuthor(authorService.get(dto.getAuthorId())); + entity.setAuthors(dto.getAuthorsId().stream().map(authorService::get).toList()); return entity; } @GetMapping public List getAll( - @RequestParam(name = "typeId", defaultValue = "-1") Long typeId, - @RequestParam(name = "authorId", defaultValue = "-1") Long authorId, - @RequestParam(name = "page", defaultValue = "0") int page, - @RequestParam(name = "size", defaultValue = Constants.DEFAULT_PAGE_SIZE) int size) { - return itemService.getAll(typeId, authorId).stream().map(this::toDto).toList(); + @RequestParam(name = "typeId", defaultValue = "-1") Long typeId, + @RequestParam(name = "page", defaultValue = "0") int page, + @RequestParam(name = "size", defaultValue = Constants.DEFAULT_PAGE_SIZE) int size) { + return bookService.getAll(typeId).stream().map(this::toDto).toList(); } @GetMapping("/{id}") public BookDto get(@PathVariable(name = "id") Long id) { - return toDto(itemService.get(id)); + return toDto(bookService.get(id)); } @PostMapping public BookDto create(@RequestBody @Valid BookDto dto) { - return toDto(itemService.create(toEntity(dto))); + return toDto(bookService.create(toEntity(dto))); } @PutMapping("/{id}") public BookDto update(@PathVariable(name = "id") Long id, @RequestBody BookDto dto) { - return toDto(itemService.update(id, toEntity(dto))); + return toDto(bookService.update(id, toEntity(dto))); } @DeleteMapping("/{id}") public BookDto delete(@PathVariable(name = "id") Long id) { - return toDto(itemService.delete(id)); + return toDto(bookService.delete(id)); } + + @GetMapping("/{bookId}/users/number") + public int getBookSubscribersNumber(@PathVariable(name = "bookId") Long bookId) { + return bookService.getBookSubscribersNumber(bookId); + } } diff --git a/SpringApp/library/src/main/java/com/ip/library/books/api/BookDto.java b/SpringApp/library/src/main/java/com/ip/library/books/api/BookDto.java index db6aad7..5c1ccd2 100644 --- a/SpringApp/library/src/main/java/com/ip/library/books/api/BookDto.java +++ b/SpringApp/library/src/main/java/com/ip/library/books/api/BookDto.java @@ -1,5 +1,7 @@ package com.ip.library.books.api; +import java.util.List; + import com.fasterxml.jackson.annotation.JsonProperty; import jakarta.validation.constraints.Min; @@ -15,8 +17,7 @@ public class BookDto { @Min(1) private Long typeId; @NotNull - @Min(1) - private Long authorId; + private List authorsId; public Long getId() { return id; @@ -34,11 +35,11 @@ public class BookDto { this.typeId = typeId; } - public Long getAuthorId() { - return authorId; + public List getAuthorsId() { + return authorsId; } - public void setAuthorId(Long authorId) { - this.authorId = authorId; + public void setAuthorId(List authorsId) { + this.authorsId = authorsId; } } diff --git a/SpringApp/library/src/main/java/com/ip/library/books/model/BookEntity.java b/SpringApp/library/src/main/java/com/ip/library/books/model/BookEntity.java index 01d7365..568288c 100644 --- a/SpringApp/library/src/main/java/com/ip/library/books/model/BookEntity.java +++ b/SpringApp/library/src/main/java/com/ip/library/books/model/BookEntity.java @@ -1,19 +1,22 @@ package com.ip.library.books.model; +import java.util.ArrayList; import java.util.HashSet; +import java.util.List; import java.util.Objects; import java.util.Set; import com.ip.library.core.model.BaseEntity; +import com.ip.library.favorites.model.FavoriteEntity; import com.ip.library.types.model.TypeEntity; -import com.ip.library.users.model.UserEntity; +import jakarta.persistence.CascadeType; import jakarta.persistence.Column; import jakarta.persistence.Entity; -import jakarta.persistence.FetchType; import jakarta.persistence.JoinColumn; import jakarta.persistence.ManyToMany; import jakarta.persistence.ManyToOne; +import jakarta.persistence.OneToMany; import jakarta.persistence.OrderBy; import jakarta.persistence.Table; @@ -25,25 +28,26 @@ public class BookEntity extends BaseEntity { @Column(nullable = false, unique = true, length = 50) private String name; @ManyToOne - @JoinColumn(name = "typeId", nullable = false) + @JoinColumn(name = "type_id", nullable = false) @OrderBy("id ASC") private TypeEntity type; - @ManyToOne - @JoinColumn(name = "authorId", nullable = false) + @ManyToMany(mappedBy = "books") @OrderBy("id ASC") - private AuthorEntity author; - @ManyToMany(mappedBy = "books", fetch = FetchType.EAGER) - @OrderBy("id ASC") - private Set users = new HashSet<>(); + private List authors = new ArrayList<>(); public BookEntity() { super(); } - public BookEntity(String name, TypeEntity type, AuthorEntity author) { + public BookEntity(String name, TypeEntity type) { this.name = name; this.type = type; - this.author = author; + } + + public BookEntity(String name, TypeEntity type, List authors) { + this.name = name; + this.type = type; + this.authors = authors; } public String getName() { @@ -62,41 +66,17 @@ public class BookEntity extends BaseEntity { this.type = type; } - public AuthorEntity getAuthor() { - return author; + public List getAuthors() { + return authors; } - public void setAuthor(AuthorEntity author) { - this.author = author; - } - - public Set getUsers() { - return users; - } - - public void setUsers(Set users) { - this.users = users; - } - - public UserEntity addUser(UserEntity user) { - users.add(user); - if (!user.getBooks().contains(this)){ - user.getBooks().add(this); - } - return user; - } - - public UserEntity removeUser(UserEntity user) { - users.remove(user); - if (user.getBooks().contains(this)) { - user.getBooks().remove(this); - } - return user; + public void setAuthors(List authors) { + this.authors = authors; } @Override public int hashCode() { - return Objects.hash(id, type, author); + return Objects.hash(id, name, type, authors); } @Override @@ -106,10 +86,10 @@ public class BookEntity extends BaseEntity { if (obj == null || getClass() != obj.getClass()) return false; final BookEntity other = (BookEntity) obj; - return Objects.equals(other.getId(), id) - && Objects.equals(other.getName(), name) - && Objects.equals(other.getType(), type) - && Objects.equals(other.getAuthor(), author) - && Objects.equals(other.getUsers(), users); + return + Objects.equals(other.getId(), id) + && Objects.equals(other.getName(), name) + && Objects.equals(other.getType(), type) + && Objects.equals(other.getAuthors(), authors); } } diff --git a/SpringApp/library/src/main/java/com/ip/library/books/repository/BookRepository.java b/SpringApp/library/src/main/java/com/ip/library/books/repository/BookRepository.java index 7a8768f..95b8603 100644 --- a/SpringApp/library/src/main/java/com/ip/library/books/repository/BookRepository.java +++ b/SpringApp/library/src/main/java/com/ip/library/books/repository/BookRepository.java @@ -4,6 +4,7 @@ import java.util.List; import java.util.Optional; import org.springframework.data.domain.Pageable; +import org.springframework.data.jpa.repository.Query; import org.springframework.data.repository.CrudRepository; import org.springframework.data.repository.PagingAndSortingRepository; @@ -13,10 +14,14 @@ public interface BookRepository extends CrudRepository, PagingAndSortingRepository { Optional findByNameIgnoreCase(String name); + List findByTypeId(long typeId); + List findByTypeId(long typeId, Pageable pageable); - List findByAuthorId(long authorId); - List findByAuthorId(long authorId, Pageable pageable); - List findByTypeIdAndAuthorId(long typeId, long authorId); - List findByTypeIdAndAuthorId(long typeId, long authorId, Pageable pageable); + + @Query( + "select count(*) as number " + + "from FavoriteEntity f " + + "where f.book.id = ?1") + int getBookSubscribersNumber(long bookId); } diff --git a/SpringApp/library/src/main/java/com/ip/library/books/service/BookService.java b/SpringApp/library/src/main/java/com/ip/library/books/service/BookService.java index a658788..0557de8 100644 --- a/SpringApp/library/src/main/java/com/ip/library/books/service/BookService.java +++ b/SpringApp/library/src/main/java/com/ip/library/books/service/BookService.java @@ -33,32 +33,22 @@ public class BookService { } @Transactional(readOnly = true) - public List getAll(long typeId, long authorId) { - if (typeId <= 0L && authorId <= 0L) { + public List getAll(long typeId) { + if (typeId <= 0L) { return getAll(); } - if (typeId <= 0L){ - return repository.findByAuthorId(authorId); - } - if (authorId <= 0L){ - return repository.findByTypeId(typeId); - } - return repository.findByTypeIdAndAuthorId(typeId, authorId); + return repository.findByTypeId(typeId); } @Transactional(readOnly = true) - public List getAll(long typeId, long authorId, int page, int size) { + public List getAll(long typeId, int page, int size) { PageRequest pageRequest = PageRequest.of(page, size); - if (typeId <= 0L && authorId <= 0L) { - return StreamSupport.stream(repository.findAll(pageRequest).spliterator(), false).toList(); + if (typeId <= 0L) { + return StreamSupport.stream( + repository.findAll(pageRequest).spliterator(), false + ).toList(); } - if (typeId <= 0L){ - return repository.findByAuthorId(authorId, pageRequest); - } - if (authorId <= 0L){ - return repository.findByTypeId(typeId, pageRequest); - } - return repository.findByTypeIdAndAuthorId(typeId, authorId, pageRequest); + return repository.findByTypeId(typeId, pageRequest); } @Transactional(readOnly = true) @@ -85,7 +75,7 @@ public class BookService { checkNameUniqueness(entity.getName()); existsEntity.setName(entity.getName()); existsEntity.setType(entity.getType()); - existsEntity.setAuthor(entity.getAuthor()); + existsEntity.setAuthors(entity.getAuthors()); return repository.save(existsEntity); } @@ -95,4 +85,9 @@ public class BookService { repository.delete(existsEntity); return existsEntity; } + + @Transactional(readOnly = true) + public int getBookSubscribersNumber(long bookId) { + return repository.getBookSubscribersNumber(bookId); + } } diff --git a/SpringApp/library/src/main/java/com/ip/library/favorites/api/FavoriteController.java b/SpringApp/library/src/main/java/com/ip/library/favorites/api/FavoriteController.java deleted file mode 100644 index 317a931..0000000 --- a/SpringApp/library/src/main/java/com/ip/library/favorites/api/FavoriteController.java +++ /dev/null @@ -1,56 +0,0 @@ -package com.ip.library.favorites.api; - -import org.springframework.web.bind.annotation.RestController; - -import java.util.List; - -import org.modelmapper.ModelMapper; -import org.springframework.web.bind.annotation.DeleteMapping; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.PathVariable; -import org.springframework.web.bind.annotation.RequestMapping; - -import com.ip.library.books.api.BookDto; -import com.ip.library.books.model.BookEntity; -import com.ip.library.core.configuration.Constants; -import com.ip.library.favorites.service.FavoriteService; - - -@RestController -@RequestMapping(Constants.API_URL + "/favorities") -public class FavoriteController { - private FavoriteService favoriteService; - private final ModelMapper modelMapper; - - public FavoriteController (FavoriteService favorityService, ModelMapper modelMapper) { - this.favoriteService = favorityService; - this.modelMapper = modelMapper; - } - private BookDto toBookDto (BookEntity entity) { - return modelMapper.map(entity, BookDto.class); - } - - @GetMapping("/user/{userId}/books/{bookId}") - public boolean addFavorite( - @PathVariable(name = "userId") Long userId, - @PathVariable(name = "bookId") Long bookId) { - return favoriteService.addFavorite(userId, bookId); - } - - @DeleteMapping("/user/{userId}/books/{bookId}") - public boolean removeFavorite( - @PathVariable(name = "userId") Long userId, - @PathVariable(name = "bookId") Long bookId) { - return favoriteService.removeFavorite(userId, bookId); - } - - @GetMapping("/user/{userId}/books") - public List getUserFavorites(@PathVariable(name = "userId") Long userId) { - return favoriteService.getUserFavorities(userId).stream().map(this::toBookDto).toList(); - } - - @GetMapping("/book/{bookId}/users/number") - public int getBookSubscribersNumber(@PathVariable(name = "bookId") Long bookId) { - return favoriteService.getBookSubscribersNumber(bookId); - } -} diff --git a/SpringApp/library/src/main/java/com/ip/library/favorites/model/FavoriteEntity.java b/SpringApp/library/src/main/java/com/ip/library/favorites/model/FavoriteEntity.java new file mode 100644 index 0000000..e3acc71 --- /dev/null +++ b/SpringApp/library/src/main/java/com/ip/library/favorites/model/FavoriteEntity.java @@ -0,0 +1,79 @@ +package com.ip.library.favorites.model; + +import java.util.Objects; + +import com.ip.library.books.model.BookEntity; +import com.ip.library.users.model.UserEntity; + +import jakarta.persistence.EmbeddedId; +import jakarta.persistence.Entity; +import jakarta.persistence.JoinColumn; +import jakarta.persistence.ManyToOne; +import jakarta.persistence.MapsId; +import jakarta.persistence.Table; + +@Entity +@Table(name = "favorites") +public class FavoriteEntity { + @EmbeddedId + private UserBookId id = new UserBookId(); + @ManyToOne + @MapsId("userId") + @JoinColumn(name = "user_id") + private UserEntity user; + @ManyToOne + @MapsId("bookId") + @JoinColumn(name = "book_id") + private BookEntity book; + + public FavoriteEntity() {} + + public FavoriteEntity(UserEntity user, BookEntity book) { + this.user = user; + this.book = book; + } + + public void setId(UserBookId id) { + this.id = id; + } + + public UserBookId getId() { + return id; + } + + public void setUser(UserEntity user) { + this.user = user; + if (!user.getFavorites().contains(this)) + user.getFavorites().add(this); + } + + public UserEntity getUser() { + return user; + } + + public void setBook(BookEntity book) { + this.book = book; + } + + public BookEntity getBook() { + return book; + } + + @Override + public int hashCode() { + return Objects.hash(id, user.getId(), book.getId()); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null || getClass() != obj.getClass()) + return false; + final FavoriteEntity other = (FavoriteEntity) obj; + return + Objects.equals(other.getId(), id) && + Objects.equals(other.getUser().getId(), user.getId()) && + Objects.equals(other.getBook().getId(), book.getId()); + } +} diff --git a/SpringApp/library/src/main/java/com/ip/library/favorites/model/UserBookId.java b/SpringApp/library/src/main/java/com/ip/library/favorites/model/UserBookId.java new file mode 100644 index 0000000..0a39979 --- /dev/null +++ b/SpringApp/library/src/main/java/com/ip/library/favorites/model/UserBookId.java @@ -0,0 +1,55 @@ +package com.ip.library.favorites.model; + +import java.util.Objects; +import java.util.Optional; + +import jakarta.persistence.Embeddable; + +@Embeddable +public class UserBookId { + private Long userId; + private Long bookId; + + public UserBookId() {} + + public UserBookId(Long userId, Long bookId) { + this.userId = userId; + this.bookId = bookId; + } + + public void setUserId(Long userId) { + this.userId = userId; + } + + public Long getUserId() { + return userId; + } + + public void setBookId(Long bookId) { + this.bookId = bookId; + } + + public Long getBookId() { + return bookId; + } + + @Override + public int hashCode() { + return Objects.hash( + Optional.ofNullable(userId).orElse(-1L), + Optional.ofNullable(bookId).orElse(-1L) + ); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null || getClass() != obj.getClass()) + return false; + UserBookId other = (UserBookId) obj; + return + Objects.equals(other.userId, userId) && + Objects.equals(other.bookId, bookId); + } +} diff --git a/SpringApp/library/src/main/java/com/ip/library/favorites/service/FavoriteService.java b/SpringApp/library/src/main/java/com/ip/library/favorites/service/FavoriteService.java deleted file mode 100644 index 09682be..0000000 --- a/SpringApp/library/src/main/java/com/ip/library/favorites/service/FavoriteService.java +++ /dev/null @@ -1,47 +0,0 @@ -package com.ip.library.favorites.service; - -import java.util.Set; - -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; - -import com.ip.library.books.model.BookEntity; -import com.ip.library.books.service.BookService; -import com.ip.library.users.model.UserEntity; -import com.ip.library.users.service.UserService; -@Service -public class FavoriteService { - BookService bookService; - UserService userService; - - public FavoriteService (BookService bookService, UserService userService) { - this.bookService = bookService; - this.userService = userService; - } - - @Transactional - public boolean addFavorite(long userId, long bookId) { - final UserEntity existsUser = userService.get(userId); - final BookEntity book = bookService.get(bookId); - existsUser.addBook(book); - return true; - } - - @Transactional - public boolean removeFavorite(long userId, long bookId) { - final UserEntity existsUser = userService.get(userId); - final BookEntity book = bookService.get(bookId); - existsUser.removeBook(book); - return true; - } - - @Transactional(readOnly = true) - public Set getUserFavorities (long userId) { - return userService.get(userId).getBooks(); - } - - @Transactional(readOnly = true) - public int getBookSubscribersNumber(long bookId) { - return bookService.get(bookId).getUsers().size(); - } -} diff --git a/SpringApp/library/src/main/java/com/ip/library/types/model/TypeEntity.java b/SpringApp/library/src/main/java/com/ip/library/types/model/TypeEntity.java index 9bd403d..61d97e6 100644 --- a/SpringApp/library/src/main/java/com/ip/library/types/model/TypeEntity.java +++ b/SpringApp/library/src/main/java/com/ip/library/types/model/TypeEntity.java @@ -42,8 +42,9 @@ public class TypeEntity extends BaseEntity { if (obj == null || getClass() != obj.getClass()) return false; final TypeEntity other = (TypeEntity) obj; - return Objects.equals(other.getId(), id) - && Objects.equals(other.getName(), name); + return + Objects.equals(other.getId(), id) + && Objects.equals(other.getName(), name); } } diff --git a/SpringApp/library/src/main/java/com/ip/library/users/api/UserController.java b/SpringApp/library/src/main/java/com/ip/library/users/api/UserController.java index 62dc82c..95696dd 100644 --- a/SpringApp/library/src/main/java/com/ip/library/users/api/UserController.java +++ b/SpringApp/library/src/main/java/com/ip/library/users/api/UserController.java @@ -1,5 +1,7 @@ package com.ip.library.users.api; +import java.util.List; + import org.modelmapper.ModelMapper; import org.springframework.web.bind.annotation.DeleteMapping; import org.springframework.web.bind.annotation.GetMapping; @@ -11,6 +13,8 @@ import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; +import com.ip.library.books.api.BookDto; +import com.ip.library.books.model.BookEntity; import com.ip.library.core.api.PageDto; import com.ip.library.core.api.PageDtoMapper; import com.ip.library.core.configuration.Constants; @@ -30,11 +34,14 @@ public class UserController { this.modelMapper = modelMapper; } - private UserDto toDto(UserEntity entity) { + private UserDto toUserDto(UserEntity entity) { return modelMapper.map(entity, UserDto.class); } + private BookDto toBookDto (BookEntity entity) { + return modelMapper.map(entity, BookDto.class); + } - private UserEntity toEntity(UserDto dto) { + private UserEntity toUserEntity(UserDto dto) { return modelMapper.map(dto, UserEntity.class); } @@ -42,31 +49,50 @@ public class UserController { public PageDto getAll( @RequestParam(name = "page", defaultValue = "0") int page, @RequestParam(name = "size", defaultValue = Constants.DEFAULT_PAGE_SIZE) int size) { - return PageDtoMapper.toDto(userService.getAll(page, size), this::toDto); + return PageDtoMapper.toDto(userService.getAll(page, size), this::toUserDto); } @GetMapping("/{id}") public UserDto get(@PathVariable(name = "id") Long id) { - return toDto(userService.get(id)); + return toUserDto(userService.get(id)); } @PostMapping public UserDto create(@RequestBody @Valid UserDto dto) { - return toDto(userService.create(toEntity(dto))); + return toUserDto(userService.create(toUserEntity(dto))); } @PutMapping("/{id}") public UserDto update(@PathVariable(name = "id") Long id, @RequestBody UserDto dto) { - return toDto(userService.update(id, toEntity(dto))); + return toUserDto(userService.update(id, toUserEntity(dto))); } @DeleteMapping("/{id}") public UserDto delete(@PathVariable(name = "id") Long id) { - return toDto(userService.delete(id)); + return toUserDto(userService.delete(id)); } @PutMapping("/password/{id}") public UserDto changePassword(@PathVariable(name = "id") Long id, @RequestBody String newPassword) { - return toDto(userService.changePassword(id, newPassword)); + return toUserDto(userService.changePassword(id, newPassword)); } + + @DeleteMapping("/{userId}/books/{bookId}") + public boolean removeFavorite( + @PathVariable(name = "userId") Long userId, + @PathVariable(name = "bookId") Long bookId) { + return userService.removeFavorite(userId, bookId); + } + + @GetMapping("/{userId}/books/{bookId}") + public boolean addFavorite( + @PathVariable(name = "userId") Long userId, + @PathVariable(name = "bookId") Long bookId) { + return userService.addFavorite(userId, bookId); + } + + @GetMapping("/{userId}/books") + public List getUserFavorites(@PathVariable(name = "userId") Long userId) { + return userService.getUserFavorities(userId).stream().map(this::toBookDto).toList(); + } } diff --git a/SpringApp/library/src/main/java/com/ip/library/users/model/UserEntity.java b/SpringApp/library/src/main/java/com/ip/library/users/model/UserEntity.java index ef2e729..81471d1 100644 --- a/SpringApp/library/src/main/java/com/ip/library/users/model/UserEntity.java +++ b/SpringApp/library/src/main/java/com/ip/library/users/model/UserEntity.java @@ -6,14 +6,13 @@ import java.util.Set; import com.ip.library.books.model.BookEntity; import com.ip.library.core.model.BaseEntity; +import com.ip.library.favorites.model.FavoriteEntity; +import com.ip.library.favorites.model.UserBookId; import jakarta.persistence.CascadeType; import jakarta.persistence.Column; import jakarta.persistence.Entity; -import jakarta.persistence.FetchType; -import jakarta.persistence.JoinColumn; -import jakarta.persistence.JoinTable; -import jakarta.persistence.ManyToMany; +import jakarta.persistence.OneToMany; import jakarta.persistence.OrderBy; import jakarta.persistence.Table; @@ -26,14 +25,9 @@ public class UserEntity extends BaseEntity { private String password; @Column(nullable = false, unique = false, length = 20) private String role = "user"; - @ManyToMany(cascade = { CascadeType.ALL }, fetch = FetchType.EAGER) - @JoinTable( - name = "favorities", - joinColumns = { @JoinColumn(name = "userId", nullable = false) }, - inverseJoinColumns = { @JoinColumn(name = "bookId", nullable = false) } - ) + @OneToMany(mappedBy = "user", cascade = CascadeType.ALL, orphanRemoval = true) @OrderBy("id ASC") - private Set books = new HashSet<>(); + private Set favorites = new HashSet<>(); public UserEntity() { super(); @@ -72,28 +66,20 @@ public class UserEntity extends BaseEntity { this.role = role; } - public Set getBooks() { - return books; + public Set getFavorites() { + return favorites; } - public void setBooks(Set books) { - this.books = books; + public void setFavorites(Set favorites) { + this.favorites = favorites; } - public BookEntity addBook(BookEntity book) { - books.add(book); - if (!book.getUsers().contains(this)) { - book.getUsers().add(this); - } - return book; + public boolean addBook(BookEntity book) { + return favorites.add(new FavoriteEntity(this, book)); } - public BookEntity removeBook(BookEntity book) { - books.remove(book); - if (book.getUsers().contains(this)) { - book.getUsers().remove(this); - } - return book; + public boolean removeBook(BookEntity book) { + return favorites.remove(new FavoriteEntity(this, book)); } @Override @@ -108,10 +94,10 @@ public class UserEntity extends BaseEntity { if (obj == null || getClass() != obj.getClass()) return false; final UserEntity other = (UserEntity) obj; - return Objects.equals(other.getId(), id) - && Objects.equals(other.getLogin(), login) - && Objects.equals(other.getPassword(), password) - && Objects.equals(other.getRole(), role) - && Objects.equals(other.getBooks(), books); + return + Objects.equals(other.getId(), id) + && Objects.equals(other.getLogin(), login) + && Objects.equals(other.getPassword(), password) + && Objects.equals(other.getRole(), role); } } diff --git a/SpringApp/library/src/main/java/com/ip/library/users/repository/UserRepository.java b/SpringApp/library/src/main/java/com/ip/library/users/repository/UserRepository.java index 73a6bc1..47592c2 100644 --- a/SpringApp/library/src/main/java/com/ip/library/users/repository/UserRepository.java +++ b/SpringApp/library/src/main/java/com/ip/library/users/repository/UserRepository.java @@ -1,14 +1,24 @@ package com.ip.library.users.repository; +import java.util.List; import java.util.Optional; +import org.springframework.data.jpa.repository.Query; import org.springframework.data.repository.CrudRepository; import org.springframework.data.repository.PagingAndSortingRepository; +import com.ip.library.books.model.BookEntity; import com.ip.library.users.model.UserEntity; public interface UserRepository extends CrudRepository, PagingAndSortingRepository { Optional findByLoginIgnoreCase(String login); + + @Query( + "select f.book " + + "from FavoriteEntity f " + + "where f.user.id = ?1 " + + "order by f.book.id") + public List getUserFavorities(Long userId); } diff --git a/SpringApp/library/src/main/java/com/ip/library/users/service/UserService.java b/SpringApp/library/src/main/java/com/ip/library/users/service/UserService.java index 7ea2993..c035414 100644 --- a/SpringApp/library/src/main/java/com/ip/library/users/service/UserService.java +++ b/SpringApp/library/src/main/java/com/ip/library/users/service/UserService.java @@ -8,6 +8,8 @@ import org.springframework.data.domain.PageRequest; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; +import com.ip.library.books.model.BookEntity; +import com.ip.library.books.service.BookService; import com.ip.library.core.error.NotFoundException; import com.ip.library.users.model.UserEntity; import com.ip.library.users.repository.UserRepository; @@ -15,9 +17,11 @@ import com.ip.library.users.repository.UserRepository; @Service public class UserService { private final UserRepository repository; + private final BookService bookService; - public UserService(UserRepository repository) { + public UserService(UserRepository repository, BookService bookService) { this.repository = repository; + this.bookService = bookService; } private void checkLoginUniqueness(String name){ @@ -85,4 +89,23 @@ public class UserService { existsEntity.setPassword(newPassword); return repository.save(existsEntity); } + + @Transactional + public boolean addFavorite(long userId, long bookId) { + final UserEntity existsUser = get(userId); + final BookEntity book = bookService.get(bookId); + return existsUser.addBook(book); + } + + @Transactional + public boolean removeFavorite(long userId, long bookId) { + final UserEntity existsUser = get(userId); + final BookEntity book = bookService.get(bookId); + return existsUser.removeBook(book); + } + + @Transactional(readOnly = true) + public List getUserFavorities (long userId) { + return repository.getUserFavorities(userId); + } } diff --git a/SpringApp/library/src/test/java/com/ip/library/BooksTests.java b/SpringApp/library/src/test/java/com/ip/library/BooksTests.java index 48df6fe..a95b233 100644 --- a/SpringApp/library/src/test/java/com/ip/library/BooksTests.java +++ b/SpringApp/library/src/test/java/com/ip/library/BooksTests.java @@ -1,5 +1,8 @@ package com.ip.library; +import java.util.List; +import java.util.ArrayList; + import org.junit.jupiter.api.Test; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.Assertions; @@ -26,7 +29,8 @@ class BooksTests { private AuthorService authorService; private BookEntity book; private TypeEntity type; - private AuthorEntity author; + private AuthorEntity author1; + private AuthorEntity author2; @AfterEach void removeData() { @@ -40,11 +44,14 @@ class BooksTests { removeData(); type = typeService.create(new TypeEntity("type1")); var type2 = typeService.create(new TypeEntity("type2")); - author = authorService.create(new AuthorEntity("author1")); - var author2 = authorService.create(new AuthorEntity("author2")); - bookService.create(new BookEntity("book1", type, author2)); - bookService.create(new BookEntity("book2", type2, author)); - book = bookService.create(new BookEntity("book3", type, author)); + author1 = authorService.create(new AuthorEntity("author1")); + author2 = authorService.create(new AuthorEntity("author2")); + List list1 = new ArrayList<>(); + list1.add(author1); + list1.add(author2); + bookService.create(new BookEntity("book1", type)); + bookService.create(new BookEntity("book2", type2)); + book = bookService.create(new BookEntity("book3", type, list1)); } @Test @@ -52,8 +59,9 @@ class BooksTests { Assertions.assertEquals(3, bookService.getAll().size()); Assertions.assertEquals("book3", book.getName()); Assertions.assertEquals(type, book.getType()); - Assertions.assertEquals(author, book.getAuthor()); - Assertions.assertEquals(0, book.getUsers().size()); + Assertions.assertTrue(book.getAuthors().contains(author1)); + Assertions.assertTrue(book.getAuthors().contains(author2)); + Assertions.assertEquals(0, bookService.getBookSubscribersNumber(book.getId())); } @Test @@ -67,14 +75,10 @@ class BooksTests { final String testName = book.getName() + "TEST"; final TypeEntity testType = typeService.create( new TypeEntity(book.getType().getName() + "TEST")); - final AuthorEntity testAuthor = authorService.create( - new AuthorEntity(book.getAuthor().getName() + "TEST")); - book = bookService.update(book.getId(), new BookEntity( - testName, testType, testAuthor)); + book = bookService.update(book.getId(), new BookEntity(testName, testType)); Assertions.assertEquals(3, bookService.getAll().size()); Assertions.assertEquals(testName, book.getName()); Assertions.assertEquals(testType, book.getType()); - Assertions.assertEquals(testAuthor, book.getAuthor()); } @Test @@ -82,7 +86,7 @@ class BooksTests { bookService.delete(book.getId()); Assertions.assertEquals(2, bookService.getAll().size()); final BookEntity newEntity = bookService.create( - new BookEntity(book.getName(), book.getType(), book.getAuthor())); + new BookEntity(book.getName(), book.getType(), book.getAuthors())); Assertions.assertEquals(3, bookService.getAll().size()); Assertions.assertNotEquals(book.getId(), newEntity.getId()); } @@ -91,11 +95,11 @@ class BooksTests { void nullNameTest() { Assertions.assertThrows( DataIntegrityViolationException.class, - () -> bookService.create(new BookEntity(null, book.getType(), book.getAuthor())) + () -> bookService.create(new BookEntity(null, book.getType(), book.getAuthors())) ); Assertions.assertThrows( DataIntegrityViolationException.class, - () -> bookService.update(book.getId(), new BookEntity(null, book.getType(), book.getAuthor())) + () -> bookService.update(book.getId(), new BookEntity(null, book.getType(), book.getAuthors())) ); } @@ -103,23 +107,11 @@ class BooksTests { void nullTypeTest() { Assertions.assertThrows( DataIntegrityViolationException.class, - () -> bookService.create(new BookEntity(book.getName() + "TEST", null, book.getAuthor())) + () -> bookService.create(new BookEntity(book.getName() + "TEST", null, book.getAuthors())) ); Assertions.assertThrows( DataIntegrityViolationException.class, - () -> bookService.update(book.getId(), new BookEntity(book.getName() + "TEST", null, book.getAuthor())) - ); - } - - @Test - void nullAuthorTest() { - Assertions.assertThrows( - DataIntegrityViolationException.class, - () -> bookService.create(new BookEntity(book.getName() + "TEST", book.getType(), null)) - ); - Assertions.assertThrows( - DataIntegrityViolationException.class, - () -> bookService.update(book.getId(), new BookEntity(book.getName() + "TEST", book.getType(), null)) + () -> bookService.update(book.getId(), new BookEntity(book.getName() + "TEST", null, book.getAuthors())) ); } @@ -127,11 +119,11 @@ class BooksTests { void uniqueNameTest() { Assertions.assertThrows( IllegalArgumentException.class, - () -> bookService.create(new BookEntity(book.getName(), book.getType(), book.getAuthor())) + () -> bookService.create(new BookEntity(book.getName(), book.getType(), book.getAuthors())) ); Assertions.assertThrows( IllegalArgumentException.class, - () -> bookService.update(book.getId(), new BookEntity(book.getName(), book.getType(), book.getAuthor())) + () -> bookService.update(book.getId(), new BookEntity(book.getName(), book.getType(), book.getAuthors())) ); } } diff --git a/SpringApp/library/src/test/java/com/ip/library/FavoritesTests.java b/SpringApp/library/src/test/java/com/ip/library/FavoritesTests.java index 11a8bb6..f3a73a2 100644 --- a/SpringApp/library/src/test/java/com/ip/library/FavoritesTests.java +++ b/SpringApp/library/src/test/java/com/ip/library/FavoritesTests.java @@ -7,11 +7,8 @@ import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; -import com.ip.library.authors.model.AuthorEntity; -import com.ip.library.authors.service.AuthorService; import com.ip.library.books.model.BookEntity; import com.ip.library.books.service.BookService; -import com.ip.library.favorites.service.FavoriteService; import com.ip.library.types.model.TypeEntity; import com.ip.library.types.service.TypeService; import com.ip.library.users.model.UserEntity; @@ -19,16 +16,12 @@ import com.ip.library.users.service.UserService; @SpringBootTest class FavoritesTests { - @Autowired - private FavoriteService favorityService; @Autowired private BookService bookService; @Autowired private UserService userService; @Autowired private TypeService typeService; - @Autowired - private AuthorService authorService; private UserEntity user; private BookEntity book1; private BookEntity book2; @@ -36,7 +29,6 @@ class FavoritesTests { @AfterEach void removeData() { bookService.getAll().forEach(item -> bookService.delete(item.getId())); - authorService.getAll().forEach(item -> authorService.delete(item.getId())); typeService.getAll().forEach(item -> typeService.delete(item.getId())); userService.getAll().forEach(item -> userService.delete(item.getId())); } @@ -45,38 +37,41 @@ class FavoritesTests { void createData() { removeData(); TypeEntity type = typeService.create(new TypeEntity("type1")); - AuthorEntity author = authorService.create(new AuthorEntity("author1")); - book1 = bookService.create(new BookEntity("book1", type, author)); - book2 = bookService.create(new BookEntity("book2", type, author)); + book1 = bookService.create(new BookEntity("book1", type)); + book2 = bookService.create(new BookEntity("book2", type)); userService.create(new UserEntity("user1", "123")); userService.create(new UserEntity("user2", "456")); user = userService.create(new UserEntity("user3", "aqw2sed45")); } @Test - void addAndRemoveTest() { - Assertions.assertEquals(0, user.getBooks().size()); - Assertions.assertEquals(0, book1.getUsers().size()); - Assertions.assertEquals(0, book2.getUsers().size()); - favorityService.addFavorite(user.getId(), book1.getId()); + void favoritesTest() { + Assertions.assertEquals(0, userService.getUserFavorities(user.getId()).size()); + Assertions.assertEquals(0, bookService.getBookSubscribersNumber(book1.getId())); + Assertions.assertEquals(0, bookService.getBookSubscribersNumber(book2.getId())); + + userService.addFavorite(user.getId(), book1.getId()); user = userService.get(user.getId()); book1 = bookService.get(book1.getId()); - Assertions.assertEquals(1, user.getBooks().size()); - Assertions.assertEquals(1, book1.getUsers().size()); - favorityService.addFavorite(user.getId(), book2.getId()); + Assertions.assertEquals(1, userService.getUserFavorities(user.getId()).size()); + Assertions.assertEquals(1, bookService.getBookSubscribersNumber(book1.getId())); + + userService.addFavorite(user.getId(), book2.getId()); user = userService.get(user.getId()); book2 = bookService.get(book2.getId()); - Assertions.assertEquals(2, user.getBooks().size()); - Assertions.assertEquals(1, book2.getUsers().size()); - favorityService.removeFavorite(user.getId(), book1.getId()); + Assertions.assertEquals(2, userService.getUserFavorities(user.getId()).size()); + Assertions.assertEquals(1, bookService.getBookSubscribersNumber(book2.getId())); + + userService.removeFavorite(user.getId(), book1.getId()); user = userService.get(user.getId()); book1 = bookService.get(book1.getId()); - Assertions.assertEquals(1, user.getBooks().size()); - Assertions.assertEquals(0, book1.getUsers().size()); - favorityService.removeFavorite(user.getId(), book2.getId()); + Assertions.assertEquals(1, userService.getUserFavorities(user.getId()).size()); + Assertions.assertEquals(0, bookService.getBookSubscribersNumber(book1.getId())); + + userService.removeFavorite(user.getId(), book2.getId()); user = userService.get(user.getId()); book2 = bookService.get(book2.getId()); - Assertions.assertEquals(0, user.getBooks().size()); - Assertions.assertEquals(0, book2.getUsers().size()); + Assertions.assertEquals(0, userService.getUserFavorities(user.getId()).size()); + Assertions.assertEquals(0, bookService.getBookSubscribersNumber(book2.getId())); } } diff --git a/SpringApp/library/src/test/java/com/ip/library/UsersTests.java b/SpringApp/library/src/test/java/com/ip/library/UsersTests.java index 12a6f52..77d86a1 100644 --- a/SpringApp/library/src/test/java/com/ip/library/UsersTests.java +++ b/SpringApp/library/src/test/java/com/ip/library/UsersTests.java @@ -37,7 +37,7 @@ class UsersTests { Assertions.assertEquals("user3", user.getLogin()); Assertions.assertEquals("aqw2sed45", user.getPassword()); Assertions.assertEquals("user", user.getRole()); - Assertions.assertEquals(0, user.getBooks().size()); + Assertions.assertEquals(0, user.getFavorites().size()); } @Test @@ -57,7 +57,7 @@ class UsersTests { Assertions.assertEquals(oldId, user.getId()); Assertions.assertEquals(testName, user.getLogin()); Assertions.assertNotEquals(testPassword, user.getPassword()); - Assertions.assertEquals(0, user.getBooks().size()); + Assertions.assertEquals(0, userService.getUserFavorities(user.getId()).size()); } @Test -- 2.25.1 From 928639bd98f25975e587ff2949abd7031d22a7ab Mon Sep 17 00:00:00 2001 From: Zakharov_Rostislav Date: Fri, 19 Apr 2024 15:43:53 +0400 Subject: [PATCH 14/21] lab3 it works. finally --- .../com/ip/library/LibraryApplication.java | 20 ++--- .../library/authors/api/AuthorController.java | 18 ++++- .../library/authors/model/AuthorEntity.java | 29 ++++--- .../authors/repository/AuthorRepository.java | 8 +- .../authors/service/AuthorService.java | 12 ++- .../model/AuthorsBooksEntity.java | 81 +++++++++++++++++++ .../authors_books/model/AuthorsBooksId.java | 55 +++++++++++++ .../ip/library/books/api/BookController.java | 26 +++--- .../ip/library/books/model/BookEntity.java | 34 ++++---- .../books/repository/BookRepository.java | 8 ++ .../ip/library/books/service/BookService.java | 7 +- .../ip/library/users/api/UserController.java | 15 +++- .../ip/library/users/model/UserEntity.java | 1 - .../test/java/com/ip/library/BooksTests.java | 18 ++--- 14 files changed, 256 insertions(+), 76 deletions(-) create mode 100644 SpringApp/library/src/main/java/com/ip/library/authors_books/model/AuthorsBooksEntity.java create mode 100644 SpringApp/library/src/main/java/com/ip/library/authors_books/model/AuthorsBooksId.java diff --git a/SpringApp/library/src/main/java/com/ip/library/LibraryApplication.java b/SpringApp/library/src/main/java/com/ip/library/LibraryApplication.java index 73bcb0a..fba23dc 100644 --- a/SpringApp/library/src/main/java/com/ip/library/LibraryApplication.java +++ b/SpringApp/library/src/main/java/com/ip/library/LibraryApplication.java @@ -54,21 +54,17 @@ public class LibraryApplication implements CommandLineRunner { log.info("Create default authors values"); final var author1 = authorService.create(new AuthorEntity("author1")); final var author2 = authorService.create(new AuthorEntity("author2")); - - final List list1 = new ArrayList<>(); - final List list2 = new ArrayList<>(); - final List list3 = new ArrayList<>(); - - list1.add(author1); - list2.add(author2); - list3.add(author1); - list3.add(author2); log.info("Create default books values"); - final var book1 = bookService.create(new BookEntity("book1", type1, list1)); - final var book2 = bookService.create(new BookEntity("book2", type1, list2)); - final var book3 = bookService.create(new BookEntity("book3", type2, list3)); + final var book1 = bookService.create(new BookEntity("book1", type1)); + final var book2 = bookService.create(new BookEntity("book2", type1)); + final var book3 = bookService.create(new BookEntity("book3", type2)); final var book4 = bookService.create(new BookEntity("book4", type2)); + + authorService.addBook(author1.getId(), book1.getId()); + authorService.addBook(author2.getId(), book2.getId()); + authorService.addBook(author1.getId(), book3.getId()); + authorService.addBook(author2.getId(), book3.getId()); log.info("Create default users values"); final var user1 = userService.create(new UserEntity("user1", "123")); diff --git a/SpringApp/library/src/main/java/com/ip/library/authors/api/AuthorController.java b/SpringApp/library/src/main/java/com/ip/library/authors/api/AuthorController.java index 22f1a66..dbb9037 100644 --- a/SpringApp/library/src/main/java/com/ip/library/authors/api/AuthorController.java +++ b/SpringApp/library/src/main/java/com/ip/library/authors/api/AuthorController.java @@ -15,10 +15,11 @@ import org.springframework.web.bind.annotation.RestController; import com.ip.library.core.configuration.Constants; import com.ip.library.authors.model.AuthorEntity; import com.ip.library.authors.service.AuthorService; +import com.ip.library.books.api.BookDto; import com.ip.library.books.model.BookEntity; +import com.ip.library.books.service.BookService; import jakarta.validation.Valid; -import org.springframework.web.bind.annotation.RequestParam; @RestController @@ -26,11 +27,20 @@ import org.springframework.web.bind.annotation.RequestParam; public class AuthorController { private final AuthorService authorService; private final ModelMapper modelMapper; + private final BookService bookService; - public AuthorController(AuthorService authorService, ModelMapper modelMapper) { + public AuthorController(AuthorService authorService, ModelMapper modelMapper, BookService bookService) { this.authorService = authorService; this.modelMapper = modelMapper; + this.bookService = bookService; } + + private BookDto toBookDto (BookEntity entity) { + BookDto bookDto = modelMapper.map(entity, BookDto.class); + bookDto.setAuthorId(bookService.getBookAuthors( + entity.getId()).stream().map(x -> x.getId()).toList()); + return bookDto; + } private AuthorDto toDto(AuthorEntity entity) { return modelMapper.map(entity, AuthorDto.class); @@ -66,8 +76,8 @@ public class AuthorController { } @GetMapping("/{id}/books") - public List getAuthorBooks(@PathVariable(name = "id") Long id) { - return authorService.getAuthorBooks(id); + public List getAuthorBooks(@PathVariable(name = "id") Long id) { + return authorService.getAuthorBooks(id).stream().map(this::toBookDto).toList(); } } diff --git a/SpringApp/library/src/main/java/com/ip/library/authors/model/AuthorEntity.java b/SpringApp/library/src/main/java/com/ip/library/authors/model/AuthorEntity.java index 9a96e32..e1890f4 100644 --- a/SpringApp/library/src/main/java/com/ip/library/authors/model/AuthorEntity.java +++ b/SpringApp/library/src/main/java/com/ip/library/authors/model/AuthorEntity.java @@ -4,6 +4,7 @@ import java.util.HashSet; import java.util.Objects; import java.util.Set; +import com.ip.library.authors_books.model.AuthorsBooksEntity; import com.ip.library.books.model.BookEntity; import com.ip.library.core.model.BaseEntity; @@ -13,6 +14,8 @@ import jakarta.persistence.Entity; import jakarta.persistence.JoinColumn; import jakarta.persistence.JoinTable; import jakarta.persistence.ManyToMany; +import jakarta.persistence.OneToMany; +import jakarta.persistence.OrderBy; import jakarta.persistence.Table; @Entity @@ -20,13 +23,9 @@ import jakarta.persistence.Table; public class AuthorEntity extends BaseEntity { @Column(nullable = false, unique = true, length = 20) private String name; - @ManyToMany(cascade = { CascadeType.ALL }) - @JoinTable( - name = "authors_books", - joinColumns = { @JoinColumn(name = "author_id", nullable = false) }, - inverseJoinColumns = { @JoinColumn(name = "book_id", nullable = false) } - ) - private Set books = new HashSet<>(); + @OneToMany(mappedBy = "author", cascade = CascadeType.ALL, orphanRemoval = true) + @OrderBy("id ASC") + private Set authorsBooks = new HashSet<>(); public AuthorEntity() { super(); @@ -44,12 +43,20 @@ public class AuthorEntity extends BaseEntity { this.name = name; } - public Set getBooks() { - return books; + public Set getAuthorsBooks() { + return authorsBooks; } - public void setBooks(Set books) { - this.books = books; + public void setBooks(Set authorsBooks) { + this.authorsBooks = authorsBooks; + } + + public boolean addBook(BookEntity book) { + AuthorsBooksEntity entity = new AuthorsBooksEntity(this, book); + boolean result = authorsBooks.add(entity); + if (!book.getAuthorsBooks().contains(entity)) + book.getAuthorsBooks().add(entity); + return result; } @Override diff --git a/SpringApp/library/src/main/java/com/ip/library/authors/repository/AuthorRepository.java b/SpringApp/library/src/main/java/com/ip/library/authors/repository/AuthorRepository.java index 5cd00a2..78559b9 100644 --- a/SpringApp/library/src/main/java/com/ip/library/authors/repository/AuthorRepository.java +++ b/SpringApp/library/src/main/java/com/ip/library/authors/repository/AuthorRepository.java @@ -15,10 +15,10 @@ public interface AuthorRepository extends PagingAndSortingRepository { Optional findByNameIgnoreCase(String name); @Query( - "select a.books " + - "from AuthorEntity a, BookEntity b " + - "where a.id = ?1 " + - "order by b.id" + "select ab.book " + + "from AuthorsBooksEntity ab " + + "where ab.author.id = ?1 " + + "order by ab.book.id" ) List getAuthorBooks(Long authorId); } diff --git a/SpringApp/library/src/main/java/com/ip/library/authors/service/AuthorService.java b/SpringApp/library/src/main/java/com/ip/library/authors/service/AuthorService.java index a93ffcf..fa324b7 100644 --- a/SpringApp/library/src/main/java/com/ip/library/authors/service/AuthorService.java +++ b/SpringApp/library/src/main/java/com/ip/library/authors/service/AuthorService.java @@ -10,13 +10,16 @@ import com.ip.library.core.error.NotFoundException; import com.ip.library.authors.model.AuthorEntity; import com.ip.library.authors.repository.AuthorRepository; import com.ip.library.books.model.BookEntity; +import com.ip.library.books.service.BookService; @Service public class AuthorService { private final AuthorRepository repository; + private final BookService bookService; - public AuthorService(AuthorRepository repository) { + public AuthorService(AuthorRepository repository, BookService bookService) { this.repository = repository; + this.bookService = bookService; } private void checkNameUniqueness(String name) { @@ -69,4 +72,11 @@ public class AuthorService { public List getAuthorBooks(long authorId) { return repository.getAuthorBooks(authorId); } + + @Transactional + public boolean addBook(long authorId, long bookId) { + final AuthorEntity existsAuthor = get(authorId); + final BookEntity book = bookService.get(bookId); + return existsAuthor.addBook(book); + } } diff --git a/SpringApp/library/src/main/java/com/ip/library/authors_books/model/AuthorsBooksEntity.java b/SpringApp/library/src/main/java/com/ip/library/authors_books/model/AuthorsBooksEntity.java new file mode 100644 index 0000000..b5fbd3e --- /dev/null +++ b/SpringApp/library/src/main/java/com/ip/library/authors_books/model/AuthorsBooksEntity.java @@ -0,0 +1,81 @@ +package com.ip.library.authors_books.model; + +import java.util.Objects; + +import com.ip.library.authors.model.AuthorEntity; +import com.ip.library.books.model.BookEntity; + +import jakarta.persistence.EmbeddedId; +import jakarta.persistence.Entity; +import jakarta.persistence.JoinColumn; +import jakarta.persistence.ManyToOne; +import jakarta.persistence.MapsId; +import jakarta.persistence.Table; + +@Entity +@Table(name = "authors_books") +public class AuthorsBooksEntity { + @EmbeddedId + private AuthorsBooksId id = new AuthorsBooksId(); + @ManyToOne + @MapsId("authorId") + @JoinColumn(name = "author_id") + private AuthorEntity author; + @ManyToOne + @MapsId("bookId") + @JoinColumn(name = "book_id") + private BookEntity book; + + public AuthorsBooksEntity() {} + + public AuthorsBooksEntity(AuthorEntity author, BookEntity book) { + this.author = author; + this.book = book; + } + + public void setId(AuthorsBooksId id) { + this.id = id; + } + + public AuthorsBooksId getId() { + return id; + } + + public void setAuthor(AuthorEntity author) { + this.author = author; + if (!author.getAuthorsBooks().contains(this)) + author.getAuthorsBooks().add(this); + } + + public AuthorEntity getAuthor() { + return author; + } + + public void setBook(BookEntity book) { + this.book = book; + if (!book.getAuthorsBooks().contains(this)) + book.getAuthorsBooks().add(this); + } + + public BookEntity getBook() { + return book; + } + + @Override + public int hashCode() { + return Objects.hash(id, author.getId(), book.getId()); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null || getClass() != obj.getClass()) + return false; + final AuthorsBooksEntity other = (AuthorsBooksEntity) obj; + return + Objects.equals(other.getId(), id) && + Objects.equals(other.getAuthor().getId(), author.getId()) && + Objects.equals(other.getBook().getId(), book.getId()); + } +} diff --git a/SpringApp/library/src/main/java/com/ip/library/authors_books/model/AuthorsBooksId.java b/SpringApp/library/src/main/java/com/ip/library/authors_books/model/AuthorsBooksId.java new file mode 100644 index 0000000..4329897 --- /dev/null +++ b/SpringApp/library/src/main/java/com/ip/library/authors_books/model/AuthorsBooksId.java @@ -0,0 +1,55 @@ +package com.ip.library.authors_books.model; + +import java.util.Objects; +import java.util.Optional; + +import jakarta.persistence.Embeddable; + +@Embeddable +public class AuthorsBooksId { + private Long authorId; + private Long bookId; + + public AuthorsBooksId() {} + + public AuthorsBooksId(Long authorId, Long bookId) { + this.authorId = authorId; + this.bookId = bookId; + } + + public Long getAuthorId() { + return authorId; + } + + public void setAuthorId(Long authorId) { + this.authorId = authorId; + } + + public Long getBookId() { + return bookId; + } + + public void setBookId(Long bookId) { + this.bookId = bookId; + } + + @Override + public int hashCode() { + return Objects.hash( + Optional.ofNullable(authorId).orElse(-1L), + Optional.ofNullable(bookId).orElse(-1L) + ); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null || getClass() != obj.getClass()) + return false; + AuthorsBooksId other = (AuthorsBooksId) obj; + return + Objects.equals(other.authorId, authorId) && + Objects.equals(other.bookId, bookId); + } +} diff --git a/SpringApp/library/src/main/java/com/ip/library/books/api/BookController.java b/SpringApp/library/src/main/java/com/ip/library/books/api/BookController.java index 47f959b..8beb460 100644 --- a/SpringApp/library/src/main/java/com/ip/library/books/api/BookController.java +++ b/SpringApp/library/src/main/java/com/ip/library/books/api/BookController.java @@ -29,22 +29,24 @@ public class BookController { private final AuthorService authorService; private final ModelMapper modelMapper; - public BookController(BookService itemService, TypeService typeService, + public BookController(BookService bookService, TypeService typeService, AuthorService authorService, ModelMapper modelMapper) { - this.bookService = itemService; + this.bookService = bookService; this.typeService = typeService; this.authorService = authorService; this.modelMapper = modelMapper; } - - private BookDto toDto(BookEntity entity) { - return modelMapper.map(entity, BookDto.class); - } + + private BookDto toBookDto (BookEntity entity) { + BookDto bookDto = modelMapper.map(entity, BookDto.class); + bookDto.setAuthorId(bookService.getBookAuthors( + entity.getId()).stream().map(x -> x.getId()).toList()); + return bookDto; + } private BookEntity toEntity(BookDto dto) { final BookEntity entity = modelMapper.map(dto, BookEntity.class); entity.setType(typeService.get(dto.getTypeId())); - entity.setAuthors(dto.getAuthorsId().stream().map(authorService::get).toList()); return entity; } @@ -53,27 +55,27 @@ public class BookController { @RequestParam(name = "typeId", defaultValue = "-1") Long typeId, @RequestParam(name = "page", defaultValue = "0") int page, @RequestParam(name = "size", defaultValue = Constants.DEFAULT_PAGE_SIZE) int size) { - return bookService.getAll(typeId).stream().map(this::toDto).toList(); + return bookService.getAll(typeId).stream().map(this::toBookDto).toList(); } @GetMapping("/{id}") public BookDto get(@PathVariable(name = "id") Long id) { - return toDto(bookService.get(id)); + return toBookDto(bookService.get(id)); } @PostMapping public BookDto create(@RequestBody @Valid BookDto dto) { - return toDto(bookService.create(toEntity(dto))); + return toBookDto(bookService.create(toEntity(dto))); } @PutMapping("/{id}") public BookDto update(@PathVariable(name = "id") Long id, @RequestBody BookDto dto) { - return toDto(bookService.update(id, toEntity(dto))); + return toBookDto(bookService.update(id, toEntity(dto))); } @DeleteMapping("/{id}") public BookDto delete(@PathVariable(name = "id") Long id) { - return toDto(bookService.delete(id)); + return toBookDto(bookService.delete(id)); } @GetMapping("/{bookId}/users/number") diff --git a/SpringApp/library/src/main/java/com/ip/library/books/model/BookEntity.java b/SpringApp/library/src/main/java/com/ip/library/books/model/BookEntity.java index 568288c..b7c6317 100644 --- a/SpringApp/library/src/main/java/com/ip/library/books/model/BookEntity.java +++ b/SpringApp/library/src/main/java/com/ip/library/books/model/BookEntity.java @@ -7,12 +7,12 @@ import java.util.Objects; import java.util.Set; import com.ip.library.core.model.BaseEntity; -import com.ip.library.favorites.model.FavoriteEntity; import com.ip.library.types.model.TypeEntity; import jakarta.persistence.CascadeType; import jakarta.persistence.Column; import jakarta.persistence.Entity; +import jakarta.persistence.FetchType; import jakarta.persistence.JoinColumn; import jakarta.persistence.ManyToMany; import jakarta.persistence.ManyToOne; @@ -21,6 +21,7 @@ import jakarta.persistence.OrderBy; import jakarta.persistence.Table; import com.ip.library.authors.model.AuthorEntity; +import com.ip.library.authors_books.model.AuthorsBooksEntity; @Entity @Table(name = "books") @@ -31,9 +32,9 @@ public class BookEntity extends BaseEntity { @JoinColumn(name = "type_id", nullable = false) @OrderBy("id ASC") private TypeEntity type; - @ManyToMany(mappedBy = "books") + @OneToMany(mappedBy = "book", cascade = CascadeType.ALL, orphanRemoval = true) @OrderBy("id ASC") - private List authors = new ArrayList<>(); + private Set authorsBooks = new HashSet<>(); public BookEntity() { super(); @@ -44,12 +45,6 @@ public class BookEntity extends BaseEntity { this.type = type; } - public BookEntity(String name, TypeEntity type, List authors) { - this.name = name; - this.type = type; - this.authors = authors; - } - public String getName() { return name; } @@ -66,17 +61,25 @@ public class BookEntity extends BaseEntity { this.type = type; } - public List getAuthors() { - return authors; + public Set getAuthorsBooks() { + return authorsBooks; } - public void setAuthors(List authors) { - this.authors = authors; + public void setAuthors(Set authorsBooks) { + this.authorsBooks = authorsBooks; + } + + public boolean addAuthor(AuthorEntity author) { + AuthorsBooksEntity entity = new AuthorsBooksEntity(author, this); + boolean result = authorsBooks.add(entity); + if (!author.getAuthorsBooks().contains(entity)) + author.getAuthorsBooks().add(entity); + return result; } @Override public int hashCode() { - return Objects.hash(id, name, type, authors); + return Objects.hash(id, name, type); } @Override @@ -89,7 +92,6 @@ public class BookEntity extends BaseEntity { return Objects.equals(other.getId(), id) && Objects.equals(other.getName(), name) - && Objects.equals(other.getType(), type) - && Objects.equals(other.getAuthors(), authors); + && Objects.equals(other.getType(), type); } } diff --git a/SpringApp/library/src/main/java/com/ip/library/books/repository/BookRepository.java b/SpringApp/library/src/main/java/com/ip/library/books/repository/BookRepository.java index 95b8603..cd9e8f0 100644 --- a/SpringApp/library/src/main/java/com/ip/library/books/repository/BookRepository.java +++ b/SpringApp/library/src/main/java/com/ip/library/books/repository/BookRepository.java @@ -8,6 +8,7 @@ import org.springframework.data.jpa.repository.Query; import org.springframework.data.repository.CrudRepository; import org.springframework.data.repository.PagingAndSortingRepository; +import com.ip.library.authors.model.AuthorEntity; import com.ip.library.books.model.BookEntity; public interface BookRepository extends @@ -24,4 +25,11 @@ public interface BookRepository extends "from FavoriteEntity f " + "where f.book.id = ?1") int getBookSubscribersNumber(long bookId); + @Query( + "select ab.author " + + "from AuthorsBooksEntity ab " + + "where ab.book.id = ?1 " + + "order by ab.author.id" + ) + List getBookAuthors(Long bookId); } diff --git a/SpringApp/library/src/main/java/com/ip/library/books/service/BookService.java b/SpringApp/library/src/main/java/com/ip/library/books/service/BookService.java index 0557de8..5631c87 100644 --- a/SpringApp/library/src/main/java/com/ip/library/books/service/BookService.java +++ b/SpringApp/library/src/main/java/com/ip/library/books/service/BookService.java @@ -7,6 +7,7 @@ import org.springframework.data.domain.PageRequest; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; +import com.ip.library.authors.model.AuthorEntity; import com.ip.library.books.model.BookEntity; import com.ip.library.books.repository.BookRepository; import com.ip.library.core.error.NotFoundException; @@ -75,7 +76,6 @@ public class BookService { checkNameUniqueness(entity.getName()); existsEntity.setName(entity.getName()); existsEntity.setType(entity.getType()); - existsEntity.setAuthors(entity.getAuthors()); return repository.save(existsEntity); } @@ -90,4 +90,9 @@ public class BookService { public int getBookSubscribersNumber(long bookId) { return repository.getBookSubscribersNumber(bookId); } + + @Transactional(readOnly = true) + public List getBookAuthors(long bookId) { + return repository.getBookAuthors(bookId); + } } diff --git a/SpringApp/library/src/main/java/com/ip/library/users/api/UserController.java b/SpringApp/library/src/main/java/com/ip/library/users/api/UserController.java index 95696dd..c3a47c5 100644 --- a/SpringApp/library/src/main/java/com/ip/library/users/api/UserController.java +++ b/SpringApp/library/src/main/java/com/ip/library/users/api/UserController.java @@ -15,6 +15,7 @@ import org.springframework.web.bind.annotation.RestController; import com.ip.library.books.api.BookDto; import com.ip.library.books.model.BookEntity; +import com.ip.library.books.service.BookService; import com.ip.library.core.api.PageDto; import com.ip.library.core.api.PageDtoMapper; import com.ip.library.core.configuration.Constants; @@ -28,18 +29,24 @@ import jakarta.validation.Valid; public class UserController { private final UserService userService; private final ModelMapper modelMapper; + private final BookService bookService; - public UserController(UserService userService, ModelMapper modelMapper) { + public UserController(UserService userService, ModelMapper modelMapper, BookService bookService) { this.userService = userService; this.modelMapper = modelMapper; + this.bookService = bookService; } + + private BookDto toBookDto (BookEntity entity) { + BookDto bookDto = modelMapper.map(entity, BookDto.class); + bookDto.setAuthorId(bookService.getBookAuthors( + entity.getId()).stream().map(x -> x.getId()).toList()); + return bookDto; + } private UserDto toUserDto(UserEntity entity) { return modelMapper.map(entity, UserDto.class); } - private BookDto toBookDto (BookEntity entity) { - return modelMapper.map(entity, BookDto.class); - } private UserEntity toUserEntity(UserDto dto) { return modelMapper.map(dto, UserEntity.class); diff --git a/SpringApp/library/src/main/java/com/ip/library/users/model/UserEntity.java b/SpringApp/library/src/main/java/com/ip/library/users/model/UserEntity.java index 81471d1..756654a 100644 --- a/SpringApp/library/src/main/java/com/ip/library/users/model/UserEntity.java +++ b/SpringApp/library/src/main/java/com/ip/library/users/model/UserEntity.java @@ -7,7 +7,6 @@ import java.util.Set; import com.ip.library.books.model.BookEntity; import com.ip.library.core.model.BaseEntity; import com.ip.library.favorites.model.FavoriteEntity; -import com.ip.library.favorites.model.UserBookId; import jakarta.persistence.CascadeType; import jakarta.persistence.Column; diff --git a/SpringApp/library/src/test/java/com/ip/library/BooksTests.java b/SpringApp/library/src/test/java/com/ip/library/BooksTests.java index a95b233..a72ea75 100644 --- a/SpringApp/library/src/test/java/com/ip/library/BooksTests.java +++ b/SpringApp/library/src/test/java/com/ip/library/BooksTests.java @@ -51,7 +51,7 @@ class BooksTests { list1.add(author2); bookService.create(new BookEntity("book1", type)); bookService.create(new BookEntity("book2", type2)); - book = bookService.create(new BookEntity("book3", type, list1)); + book = bookService.create(new BookEntity("book3", type)); } @Test @@ -59,8 +59,6 @@ class BooksTests { Assertions.assertEquals(3, bookService.getAll().size()); Assertions.assertEquals("book3", book.getName()); Assertions.assertEquals(type, book.getType()); - Assertions.assertTrue(book.getAuthors().contains(author1)); - Assertions.assertTrue(book.getAuthors().contains(author2)); Assertions.assertEquals(0, bookService.getBookSubscribersNumber(book.getId())); } @@ -86,7 +84,7 @@ class BooksTests { bookService.delete(book.getId()); Assertions.assertEquals(2, bookService.getAll().size()); final BookEntity newEntity = bookService.create( - new BookEntity(book.getName(), book.getType(), book.getAuthors())); + new BookEntity(book.getName(), book.getType())); Assertions.assertEquals(3, bookService.getAll().size()); Assertions.assertNotEquals(book.getId(), newEntity.getId()); } @@ -95,11 +93,11 @@ class BooksTests { void nullNameTest() { Assertions.assertThrows( DataIntegrityViolationException.class, - () -> bookService.create(new BookEntity(null, book.getType(), book.getAuthors())) + () -> bookService.create(new BookEntity(null, book.getType())) ); Assertions.assertThrows( DataIntegrityViolationException.class, - () -> bookService.update(book.getId(), new BookEntity(null, book.getType(), book.getAuthors())) + () -> bookService.update(book.getId(), new BookEntity(null, book.getType())) ); } @@ -107,11 +105,11 @@ class BooksTests { void nullTypeTest() { Assertions.assertThrows( DataIntegrityViolationException.class, - () -> bookService.create(new BookEntity(book.getName() + "TEST", null, book.getAuthors())) + () -> bookService.create(new BookEntity(book.getName() + "TEST", null)) ); Assertions.assertThrows( DataIntegrityViolationException.class, - () -> bookService.update(book.getId(), new BookEntity(book.getName() + "TEST", null, book.getAuthors())) + () -> bookService.update(book.getId(), new BookEntity(book.getName() + "TEST", null)) ); } @@ -119,11 +117,11 @@ class BooksTests { void uniqueNameTest() { Assertions.assertThrows( IllegalArgumentException.class, - () -> bookService.create(new BookEntity(book.getName(), book.getType(), book.getAuthors())) + () -> bookService.create(new BookEntity(book.getName(), book.getType())) ); Assertions.assertThrows( IllegalArgumentException.class, - () -> bookService.update(book.getId(), new BookEntity(book.getName(), book.getType(), book.getAuthors())) + () -> bookService.update(book.getId(), new BookEntity(book.getName(), book.getType())) ); } } -- 2.25.1 From 8e13c1654eba79cacefa18b7c75f3edba1d39465 Mon Sep 17 00:00:00 2001 From: Zakharov_Rostislav Date: Fri, 26 Apr 2024 13:53:06 +0400 Subject: [PATCH 15/21] lab-3 tasks were done but some mistakes --- .../com/ip/library/LibraryApplication.java | 8 ++-- .../library/authors/api/AuthorController.java | 22 +--------- .../authors/repository/AuthorRepository.java | 10 ----- .../authors/service/AuthorService.java | 18 +------- .../ip/library/books/api/BookController.java | 19 +++++---- .../ip/library/books/model/BookEntity.java | 3 +- .../books/repository/BookRepository.java | 42 +++++++++++++++---- .../ip/library/books/service/BookService.java | 42 ++++++++++--------- .../ip/library/users/api/UserController.java | 15 ++++--- .../users/repository/UserRepository.java | 8 ++++ .../ip/library/users/service/UserService.java | 5 +++ 11 files changed, 97 insertions(+), 95 deletions(-) diff --git a/SpringApp/library/src/main/java/com/ip/library/LibraryApplication.java b/SpringApp/library/src/main/java/com/ip/library/LibraryApplication.java index fba23dc..ab43fc5 100644 --- a/SpringApp/library/src/main/java/com/ip/library/LibraryApplication.java +++ b/SpringApp/library/src/main/java/com/ip/library/LibraryApplication.java @@ -61,10 +61,10 @@ public class LibraryApplication implements CommandLineRunner { final var book3 = bookService.create(new BookEntity("book3", type2)); final var book4 = bookService.create(new BookEntity("book4", type2)); - authorService.addBook(author1.getId(), book1.getId()); - authorService.addBook(author2.getId(), book2.getId()); - authorService.addBook(author1.getId(), book3.getId()); - authorService.addBook(author2.getId(), book3.getId()); + bookService.addAuthor(author1.getId(), book1.getId()); + bookService.addAuthor(author2.getId(), book2.getId()); + bookService.addAuthor(author1.getId(), book3.getId()); + bookService.addAuthor(author2.getId(), book3.getId()); log.info("Create default users values"); final var user1 = userService.create(new UserEntity("user1", "123")); diff --git a/SpringApp/library/src/main/java/com/ip/library/authors/api/AuthorController.java b/SpringApp/library/src/main/java/com/ip/library/authors/api/AuthorController.java index dbb9037..31cf660 100644 --- a/SpringApp/library/src/main/java/com/ip/library/authors/api/AuthorController.java +++ b/SpringApp/library/src/main/java/com/ip/library/authors/api/AuthorController.java @@ -15,9 +15,6 @@ import org.springframework.web.bind.annotation.RestController; import com.ip.library.core.configuration.Constants; import com.ip.library.authors.model.AuthorEntity; import com.ip.library.authors.service.AuthorService; -import com.ip.library.books.api.BookDto; -import com.ip.library.books.model.BookEntity; -import com.ip.library.books.service.BookService; import jakarta.validation.Valid; @@ -27,20 +24,11 @@ import jakarta.validation.Valid; public class AuthorController { private final AuthorService authorService; private final ModelMapper modelMapper; - private final BookService bookService; - public AuthorController(AuthorService authorService, ModelMapper modelMapper, BookService bookService) { + public AuthorController(AuthorService authorService, ModelMapper modelMapper) { this.authorService = authorService; this.modelMapper = modelMapper; - this.bookService = bookService; } - - private BookDto toBookDto (BookEntity entity) { - BookDto bookDto = modelMapper.map(entity, BookDto.class); - bookDto.setAuthorId(bookService.getBookAuthors( - entity.getId()).stream().map(x -> x.getId()).toList()); - return bookDto; - } private AuthorDto toDto(AuthorEntity entity) { return modelMapper.map(entity, AuthorDto.class); @@ -73,11 +61,5 @@ public class AuthorController { @DeleteMapping("/{id}") public AuthorDto delete(@PathVariable(name = "id") Long id) { return toDto(authorService.delete(id)); - } - - @GetMapping("/{id}/books") - public List getAuthorBooks(@PathVariable(name = "id") Long id) { - return authorService.getAuthorBooks(id).stream().map(this::toBookDto).toList(); - } - + } } diff --git a/SpringApp/library/src/main/java/com/ip/library/authors/repository/AuthorRepository.java b/SpringApp/library/src/main/java/com/ip/library/authors/repository/AuthorRepository.java index 78559b9..13c44dd 100644 --- a/SpringApp/library/src/main/java/com/ip/library/authors/repository/AuthorRepository.java +++ b/SpringApp/library/src/main/java/com/ip/library/authors/repository/AuthorRepository.java @@ -1,24 +1,14 @@ package com.ip.library.authors.repository; -import java.util.List; import java.util.Optional; -import org.springframework.data.jpa.repository.Query; import org.springframework.data.repository.CrudRepository; import org.springframework.data.repository.PagingAndSortingRepository; import com.ip.library.authors.model.AuthorEntity; -import com.ip.library.books.model.BookEntity; public interface AuthorRepository extends CrudRepository, PagingAndSortingRepository { Optional findByNameIgnoreCase(String name); - @Query( - "select ab.book " + - "from AuthorsBooksEntity ab " + - "where ab.author.id = ?1 " + - "order by ab.book.id" - ) - List getAuthorBooks(Long authorId); } diff --git a/SpringApp/library/src/main/java/com/ip/library/authors/service/AuthorService.java b/SpringApp/library/src/main/java/com/ip/library/authors/service/AuthorService.java index fa324b7..27eee8f 100644 --- a/SpringApp/library/src/main/java/com/ip/library/authors/service/AuthorService.java +++ b/SpringApp/library/src/main/java/com/ip/library/authors/service/AuthorService.java @@ -9,17 +9,13 @@ import org.springframework.transaction.annotation.Transactional; import com.ip.library.core.error.NotFoundException; import com.ip.library.authors.model.AuthorEntity; import com.ip.library.authors.repository.AuthorRepository; -import com.ip.library.books.model.BookEntity; -import com.ip.library.books.service.BookService; @Service public class AuthorService { private final AuthorRepository repository; - private final BookService bookService; - public AuthorService(AuthorRepository repository, BookService bookService) { + public AuthorService(AuthorRepository repository) { this.repository = repository; - this.bookService = bookService; } private void checkNameUniqueness(String name) { @@ -67,16 +63,4 @@ public class AuthorService { repository.delete(existsEntity); return existsEntity; } - - @Transactional - public List getAuthorBooks(long authorId) { - return repository.getAuthorBooks(authorId); - } - - @Transactional - public boolean addBook(long authorId, long bookId) { - final AuthorEntity existsAuthor = get(authorId); - final BookEntity book = bookService.get(bookId); - return existsAuthor.addBook(book); - } } diff --git a/SpringApp/library/src/main/java/com/ip/library/books/api/BookController.java b/SpringApp/library/src/main/java/com/ip/library/books/api/BookController.java index 8beb460..537a191 100644 --- a/SpringApp/library/src/main/java/com/ip/library/books/api/BookController.java +++ b/SpringApp/library/src/main/java/com/ip/library/books/api/BookController.java @@ -17,7 +17,6 @@ import com.ip.library.books.model.BookEntity; import com.ip.library.books.service.BookService; import com.ip.library.core.configuration.Constants; import com.ip.library.types.service.TypeService; -import com.ip.library.authors.service.AuthorService; import jakarta.validation.Valid; @@ -26,21 +25,17 @@ import jakarta.validation.Valid; public class BookController { private final BookService bookService; private final TypeService typeService; - private final AuthorService authorService; private final ModelMapper modelMapper; - public BookController(BookService bookService, TypeService typeService, - AuthorService authorService, ModelMapper modelMapper) { + public BookController(BookService bookService, TypeService typeService, ModelMapper modelMapper) { this.bookService = bookService; this.typeService = typeService; - this.authorService = authorService; this.modelMapper = modelMapper; } private BookDto toBookDto (BookEntity entity) { BookDto bookDto = modelMapper.map(entity, BookDto.class); - bookDto.setAuthorId(bookService.getBookAuthors( - entity.getId()).stream().map(x -> x.getId()).toList()); + bookDto.setAuthorId(entity.getAuthorsBooks().stream().map(x -> x.getAuthor().getId()).toList()); return bookDto; } @@ -53,9 +48,10 @@ public class BookController { @GetMapping public List getAll( @RequestParam(name = "typeId", defaultValue = "-1") Long typeId, + @RequestParam(name = "authorId", defaultValue = "-1") Long authorId, @RequestParam(name = "page", defaultValue = "0") int page, @RequestParam(name = "size", defaultValue = Constants.DEFAULT_PAGE_SIZE) int size) { - return bookService.getAll(typeId).stream().map(this::toBookDto).toList(); + return bookService.getAll(typeId, authorId, page, size).stream().map(this::toBookDto).toList(); } @GetMapping("/{id}") @@ -81,5 +77,12 @@ public class BookController { @GetMapping("/{bookId}/users/number") public int getBookSubscribersNumber(@PathVariable(name = "bookId") Long bookId) { return bookService.getBookSubscribersNumber(bookId); + } + + @GetMapping("/{bookId}/author/{authorId}") + public boolean addAuthor( + @PathVariable(name = "bookId") Long bookId, + @PathVariable(name = "authorId") Long authorId) { + return bookService.addAuthor(authorId, bookId); } } diff --git a/SpringApp/library/src/main/java/com/ip/library/books/model/BookEntity.java b/SpringApp/library/src/main/java/com/ip/library/books/model/BookEntity.java index b7c6317..6220db1 100644 --- a/SpringApp/library/src/main/java/com/ip/library/books/model/BookEntity.java +++ b/SpringApp/library/src/main/java/com/ip/library/books/model/BookEntity.java @@ -32,7 +32,8 @@ public class BookEntity extends BaseEntity { @JoinColumn(name = "type_id", nullable = false) @OrderBy("id ASC") private TypeEntity type; - @OneToMany(mappedBy = "book", cascade = CascadeType.ALL, orphanRemoval = true) + @OneToMany(mappedBy = "book", cascade = CascadeType.ALL, + orphanRemoval = true, fetch = FetchType.EAGER) @OrderBy("id ASC") private Set authorsBooks = new HashSet<>(); diff --git a/SpringApp/library/src/main/java/com/ip/library/books/repository/BookRepository.java b/SpringApp/library/src/main/java/com/ip/library/books/repository/BookRepository.java index cd9e8f0..a0262f2 100644 --- a/SpringApp/library/src/main/java/com/ip/library/books/repository/BookRepository.java +++ b/SpringApp/library/src/main/java/com/ip/library/books/repository/BookRepository.java @@ -8,7 +8,6 @@ import org.springframework.data.jpa.repository.Query; import org.springframework.data.repository.CrudRepository; import org.springframework.data.repository.PagingAndSortingRepository; -import com.ip.library.authors.model.AuthorEntity; import com.ip.library.books.model.BookEntity; public interface BookRepository extends @@ -19,17 +18,44 @@ public interface BookRepository extends List findByTypeId(long typeId); List findByTypeId(long typeId, Pageable pageable); + + @Query( + "select ab.book " + + "from AuthorsBooksEntity ab " + + "where ab.author.id = ?1 " + + "order by ab.book.id" + ) + List findByAuthorId(Long authorId); + + @Query( + "select ab.book " + + "from AuthorsBooksEntity ab " + + "where ab.author.id = ?1 " + + "order by ab.book.id" + ) + List findByAuthorId(Long authorId, Pageable pageable); + + @Query( + "select ab.book " + + "from AuthorsBooksEntity ab " + + "where ab.author.id = ?1 and " + + "ab.book.type.id = ?2 " + + "order by ab.book.id" + ) + List findByAuthorIdAndTypeId(Long authorId, Long typeId); + + @Query( + "select ab.book " + + "from AuthorsBooksEntity ab " + + "where ab.author.id = ?1 and " + + "ab.book.type.id = ?2 " + + "order by ab.book.id" + ) + List findByAuthorIdAndTypeId(Long authorId, Long typeId, Pageable pageable); @Query( "select count(*) as number " + "from FavoriteEntity f " + "where f.book.id = ?1") int getBookSubscribersNumber(long bookId); - @Query( - "select ab.author " + - "from AuthorsBooksEntity ab " + - "where ab.book.id = ?1 " + - "order by ab.author.id" - ) - List getBookAuthors(Long bookId); } diff --git a/SpringApp/library/src/main/java/com/ip/library/books/service/BookService.java b/SpringApp/library/src/main/java/com/ip/library/books/service/BookService.java index 5631c87..610bdfd 100644 --- a/SpringApp/library/src/main/java/com/ip/library/books/service/BookService.java +++ b/SpringApp/library/src/main/java/com/ip/library/books/service/BookService.java @@ -8,6 +8,7 @@ import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import com.ip.library.authors.model.AuthorEntity; +import com.ip.library.authors.service.AuthorService; import com.ip.library.books.model.BookEntity; import com.ip.library.books.repository.BookRepository; import com.ip.library.core.error.NotFoundException; @@ -15,9 +16,11 @@ import com.ip.library.core.error.NotFoundException; @Service public class BookService { private final BookRepository repository; + private final AuthorService authorService; - public BookService(BookRepository repository) { + public BookService(BookRepository repository, AuthorService authorService) { this.repository = repository; + this.authorService = authorService; } private void checkNameUniqueness(String name){ @@ -34,22 +37,16 @@ public class BookService { } @Transactional(readOnly = true) - public List getAll(long typeId) { - if (typeId <= 0L) { - return getAll(); - } - return repository.findByTypeId(typeId); - } - - @Transactional(readOnly = true) - public List getAll(long typeId, int page, int size) { + public List getAll(long typeId, long authorId, int page, int size) { PageRequest pageRequest = PageRequest.of(page, size); - if (typeId <= 0L) { - return StreamSupport.stream( - repository.findAll(pageRequest).spliterator(), false - ).toList(); - } - return repository.findByTypeId(typeId, pageRequest); + if (typeId <= 0L && authorId <= 0L) + return StreamSupport.stream(repository.findAll(pageRequest).spliterator(), + false).toList(); + if (authorId <= 0L) + return repository.findByTypeId(typeId, pageRequest); + if (typeId <= 0L) + return repository.findByAuthorId(authorId, pageRequest); + return repository.findByAuthorIdAndTypeId(authorId, typeId, pageRequest); } @Transactional(readOnly = true) @@ -91,8 +88,15 @@ public class BookService { return repository.getBookSubscribersNumber(bookId); } - @Transactional(readOnly = true) - public List getBookAuthors(long bookId) { - return repository.getBookAuthors(bookId); + @Transactional + public boolean addAuthor(long authorId, long bookId) { + final AuthorEntity existsAuthor = authorService.get(authorId); + final BookEntity book = get(bookId); + return existsAuthor.addBook(book); + } + + @Transactional + public List findByAuthorId(long authorId) { + return repository.findByAuthorId(authorId); } } diff --git a/SpringApp/library/src/main/java/com/ip/library/users/api/UserController.java b/SpringApp/library/src/main/java/com/ip/library/users/api/UserController.java index c3a47c5..ba8b077 100644 --- a/SpringApp/library/src/main/java/com/ip/library/users/api/UserController.java +++ b/SpringApp/library/src/main/java/com/ip/library/users/api/UserController.java @@ -15,7 +15,6 @@ import org.springframework.web.bind.annotation.RestController; import com.ip.library.books.api.BookDto; import com.ip.library.books.model.BookEntity; -import com.ip.library.books.service.BookService; import com.ip.library.core.api.PageDto; import com.ip.library.core.api.PageDtoMapper; import com.ip.library.core.configuration.Constants; @@ -29,18 +28,15 @@ import jakarta.validation.Valid; public class UserController { private final UserService userService; private final ModelMapper modelMapper; - private final BookService bookService; - public UserController(UserService userService, ModelMapper modelMapper, BookService bookService) { + public UserController(UserService userService, ModelMapper modelMapper) { this.userService = userService; this.modelMapper = modelMapper; - this.bookService = bookService; } private BookDto toBookDto (BookEntity entity) { BookDto bookDto = modelMapper.map(entity, BookDto.class); - bookDto.setAuthorId(bookService.getBookAuthors( - entity.getId()).stream().map(x -> x.getId()).toList()); + bookDto.setAuthorId(entity.getAuthorsBooks().stream().map(x -> x.getAuthor().getId()).toList()); return bookDto; } @@ -99,7 +95,10 @@ public class UserController { } @GetMapping("/{userId}/books") - public List getUserFavorites(@PathVariable(name = "userId") Long userId) { - return userService.getUserFavorities(userId).stream().map(this::toBookDto).toList(); + public List getUserFavorites( + @PathVariable(name = "userId") Long userId, + @RequestParam(name = "page", defaultValue = "0") int page, + @RequestParam(name = "size", defaultValue = Constants.DEFAULT_PAGE_SIZE) int size) { + return userService.getUserFavorities(userId, page, size).stream().map(this::toBookDto).toList(); } } diff --git a/SpringApp/library/src/main/java/com/ip/library/users/repository/UserRepository.java b/SpringApp/library/src/main/java/com/ip/library/users/repository/UserRepository.java index 47592c2..087947f 100644 --- a/SpringApp/library/src/main/java/com/ip/library/users/repository/UserRepository.java +++ b/SpringApp/library/src/main/java/com/ip/library/users/repository/UserRepository.java @@ -3,6 +3,7 @@ package com.ip.library.users.repository; import java.util.List; import java.util.Optional; +import org.springframework.data.domain.Pageable; import org.springframework.data.jpa.repository.Query; import org.springframework.data.repository.CrudRepository; import org.springframework.data.repository.PagingAndSortingRepository; @@ -21,4 +22,11 @@ public interface UserRepository extends "where f.user.id = ?1 " + "order by f.book.id") public List getUserFavorities(Long userId); + + @Query( + "select f.book " + + "from FavoriteEntity f " + + "where f.user.id = ?1 " + + "order by f.book.id") + public List getUserFavorities(Long userId, Pageable pageable); } diff --git a/SpringApp/library/src/main/java/com/ip/library/users/service/UserService.java b/SpringApp/library/src/main/java/com/ip/library/users/service/UserService.java index c035414..a5977b9 100644 --- a/SpringApp/library/src/main/java/com/ip/library/users/service/UserService.java +++ b/SpringApp/library/src/main/java/com/ip/library/users/service/UserService.java @@ -108,4 +108,9 @@ public class UserService { public List getUserFavorities (long userId) { return repository.getUserFavorities(userId); } + + @Transactional(readOnly = true) + public List getUserFavorities (long userId, int page, int size) { + return repository.getUserFavorities(userId, PageRequest.of(page, size)); + } } -- 2.25.1 From 04fe7c7610f6fee0538bf1f9aa0cec6f4048a4bc Mon Sep 17 00:00:00 2001 From: Zakharov_Rostislav Date: Fri, 26 Apr 2024 14:15:16 +0400 Subject: [PATCH 16/21] lab-3 delete removeFavorite method --- .../com/ip/library/users/service/UserService.java | 7 ------- .../src/test/java/com/ip/library/FavoritesTests.java | 12 ------------ 2 files changed, 19 deletions(-) diff --git a/SpringApp/library/src/main/java/com/ip/library/users/service/UserService.java b/SpringApp/library/src/main/java/com/ip/library/users/service/UserService.java index a5977b9..e8a6aba 100644 --- a/SpringApp/library/src/main/java/com/ip/library/users/service/UserService.java +++ b/SpringApp/library/src/main/java/com/ip/library/users/service/UserService.java @@ -97,13 +97,6 @@ public class UserService { return existsUser.addBook(book); } - @Transactional - public boolean removeFavorite(long userId, long bookId) { - final UserEntity existsUser = get(userId); - final BookEntity book = bookService.get(bookId); - return existsUser.removeBook(book); - } - @Transactional(readOnly = true) public List getUserFavorities (long userId) { return repository.getUserFavorities(userId); diff --git a/SpringApp/library/src/test/java/com/ip/library/FavoritesTests.java b/SpringApp/library/src/test/java/com/ip/library/FavoritesTests.java index f3a73a2..8511bec 100644 --- a/SpringApp/library/src/test/java/com/ip/library/FavoritesTests.java +++ b/SpringApp/library/src/test/java/com/ip/library/FavoritesTests.java @@ -61,17 +61,5 @@ class FavoritesTests { book2 = bookService.get(book2.getId()); Assertions.assertEquals(2, userService.getUserFavorities(user.getId()).size()); Assertions.assertEquals(1, bookService.getBookSubscribersNumber(book2.getId())); - - userService.removeFavorite(user.getId(), book1.getId()); - user = userService.get(user.getId()); - book1 = bookService.get(book1.getId()); - Assertions.assertEquals(1, userService.getUserFavorities(user.getId()).size()); - Assertions.assertEquals(0, bookService.getBookSubscribersNumber(book1.getId())); - - userService.removeFavorite(user.getId(), book2.getId()); - user = userService.get(user.getId()); - book2 = bookService.get(book2.getId()); - Assertions.assertEquals(0, userService.getUserFavorities(user.getId()).size()); - Assertions.assertEquals(0, bookService.getBookSubscribersNumber(book2.getId())); } } -- 2.25.1 From 806651bbb636ba2b5fa752d8ee555942794a0762 Mon Sep 17 00:00:00 2001 From: Zakharov_Rostislav Date: Fri, 26 Apr 2024 14:18:28 +0400 Subject: [PATCH 17/21] lab-3 del... p.2 --- .../src/main/java/com/ip/library/users/api/UserController.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SpringApp/library/src/main/java/com/ip/library/users/api/UserController.java b/SpringApp/library/src/main/java/com/ip/library/users/api/UserController.java index ba8b077..c28a36a 100644 --- a/SpringApp/library/src/main/java/com/ip/library/users/api/UserController.java +++ b/SpringApp/library/src/main/java/com/ip/library/users/api/UserController.java @@ -84,7 +84,7 @@ public class UserController { public boolean removeFavorite( @PathVariable(name = "userId") Long userId, @PathVariable(name = "bookId") Long bookId) { - return userService.removeFavorite(userId, bookId); + return true; } @GetMapping("/{userId}/books/{bookId}") -- 2.25.1 From c58d300411f011983a6e5a7e73882d4f93736c3a Mon Sep 17 00:00:00 2001 From: Zakharov_Rostislav Date: Fri, 26 Apr 2024 14:28:07 +0400 Subject: [PATCH 18/21] lab-3 break FavoritiesTests --- .../src/test/java/com/ip/library/FavoritesTests.java | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/SpringApp/library/src/test/java/com/ip/library/FavoritesTests.java b/SpringApp/library/src/test/java/com/ip/library/FavoritesTests.java index 8511bec..65140f1 100644 --- a/SpringApp/library/src/test/java/com/ip/library/FavoritesTests.java +++ b/SpringApp/library/src/test/java/com/ip/library/FavoritesTests.java @@ -49,17 +49,5 @@ class FavoritesTests { Assertions.assertEquals(0, userService.getUserFavorities(user.getId()).size()); Assertions.assertEquals(0, bookService.getBookSubscribersNumber(book1.getId())); Assertions.assertEquals(0, bookService.getBookSubscribersNumber(book2.getId())); - - userService.addFavorite(user.getId(), book1.getId()); - user = userService.get(user.getId()); - book1 = bookService.get(book1.getId()); - Assertions.assertEquals(1, userService.getUserFavorities(user.getId()).size()); - Assertions.assertEquals(1, bookService.getBookSubscribersNumber(book1.getId())); - - userService.addFavorite(user.getId(), book2.getId()); - user = userService.get(user.getId()); - book2 = bookService.get(book2.getId()); - Assertions.assertEquals(2, userService.getUserFavorities(user.getId()).size()); - Assertions.assertEquals(1, bookService.getBookSubscribersNumber(book2.getId())); } } -- 2.25.1 From f03ab7e06d1e1d256a55d0d636b8abad92f422a5 Mon Sep 17 00:00:00 2001 From: Zakharov_Rostislav Date: Fri, 26 Apr 2024 14:42:14 +0400 Subject: [PATCH 19/21] lab-3 some fixes in dto --- .../main/java/com/ip/library/books/api/BookDto.java | 8 ++++++++ .../main/java/com/ip/library/users/api/UserDto.java | 10 +++++----- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/SpringApp/library/src/main/java/com/ip/library/books/api/BookDto.java b/SpringApp/library/src/main/java/com/ip/library/books/api/BookDto.java index 5c1ccd2..41346ef 100644 --- a/SpringApp/library/src/main/java/com/ip/library/books/api/BookDto.java +++ b/SpringApp/library/src/main/java/com/ip/library/books/api/BookDto.java @@ -27,6 +27,14 @@ public class BookDto { this.id = id; } + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + public Long getTypeId() { return typeId; } diff --git a/SpringApp/library/src/main/java/com/ip/library/users/api/UserDto.java b/SpringApp/library/src/main/java/com/ip/library/users/api/UserDto.java index 747ba0e..52efe25 100644 --- a/SpringApp/library/src/main/java/com/ip/library/users/api/UserDto.java +++ b/SpringApp/library/src/main/java/com/ip/library/users/api/UserDto.java @@ -10,7 +10,7 @@ public class UserDto { private Long id; @NotBlank @Size(min = 5, max = 20) - private String name; + private String login; @JsonProperty(access = JsonProperty.Access.READ_ONLY) @NotBlank @Size(min = 5, max = 20) @@ -28,12 +28,12 @@ public class UserDto { this.id = id; } - public String getName() { - return name; + public String getLogin() { + return login; } - public void setName(String name) { - this.name = name; + public void setLogin(String name) { + this.login = name; } public String getPassword() { -- 2.25.1 From e7121a8a830c2ca16794bd8bbf874b44e1e46039 Mon Sep 17 00:00:00 2001 From: Zakharov_Rostislav Date: Fri, 26 Apr 2024 14:52:25 +0400 Subject: [PATCH 20/21] lab-3 some minor fixes --- .../main/java/com/ip/library/authors/model/AuthorEntity.java | 3 --- .../src/main/java/com/ip/library/books/model/BookEntity.java | 3 --- 2 files changed, 6 deletions(-) diff --git a/SpringApp/library/src/main/java/com/ip/library/authors/model/AuthorEntity.java b/SpringApp/library/src/main/java/com/ip/library/authors/model/AuthorEntity.java index e1890f4..1add767 100644 --- a/SpringApp/library/src/main/java/com/ip/library/authors/model/AuthorEntity.java +++ b/SpringApp/library/src/main/java/com/ip/library/authors/model/AuthorEntity.java @@ -11,9 +11,6 @@ import com.ip.library.core.model.BaseEntity; import jakarta.persistence.CascadeType; import jakarta.persistence.Column; import jakarta.persistence.Entity; -import jakarta.persistence.JoinColumn; -import jakarta.persistence.JoinTable; -import jakarta.persistence.ManyToMany; import jakarta.persistence.OneToMany; import jakarta.persistence.OrderBy; import jakarta.persistence.Table; diff --git a/SpringApp/library/src/main/java/com/ip/library/books/model/BookEntity.java b/SpringApp/library/src/main/java/com/ip/library/books/model/BookEntity.java index 6220db1..296afd5 100644 --- a/SpringApp/library/src/main/java/com/ip/library/books/model/BookEntity.java +++ b/SpringApp/library/src/main/java/com/ip/library/books/model/BookEntity.java @@ -1,8 +1,6 @@ package com.ip.library.books.model; -import java.util.ArrayList; import java.util.HashSet; -import java.util.List; import java.util.Objects; import java.util.Set; @@ -14,7 +12,6 @@ import jakarta.persistence.Column; import jakarta.persistence.Entity; import jakarta.persistence.FetchType; import jakarta.persistence.JoinColumn; -import jakarta.persistence.ManyToMany; import jakarta.persistence.ManyToOne; import jakarta.persistence.OneToMany; import jakarta.persistence.OrderBy; -- 2.25.1 From 5c24e481cf5a63a43b8043f6e7b4f5398953b80a Mon Sep 17 00:00:00 2001 From: Zakharov_Rostislav Date: Fri, 26 Apr 2024 16:08:11 +0400 Subject: [PATCH 21/21] lab-3 add tests for jpql methods and make some fixes --- .../books/repository/BookRepository.java | 19 ++--- .../ip/library/books/service/BookService.java | 18 ++++- .../users/repository/UserRepository.java | 3 +- .../ip/library/users/service/UserService.java | 2 +- .../test/java/com/ip/library/BooksTests.java | 77 +++++++++++-------- .../java/com/ip/library/FavoritesTests.java | 29 +++++-- 6 files changed, 94 insertions(+), 54 deletions(-) diff --git a/SpringApp/library/src/main/java/com/ip/library/books/repository/BookRepository.java b/SpringApp/library/src/main/java/com/ip/library/books/repository/BookRepository.java index a0262f2..2a49435 100644 --- a/SpringApp/library/src/main/java/com/ip/library/books/repository/BookRepository.java +++ b/SpringApp/library/src/main/java/com/ip/library/books/repository/BookRepository.java @@ -3,6 +3,7 @@ package com.ip.library.books.repository; import java.util.List; import java.util.Optional; +import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; import org.springframework.data.jpa.repository.Query; import org.springframework.data.repository.CrudRepository; @@ -17,31 +18,28 @@ public interface BookRepository extends List findByTypeId(long typeId); - List findByTypeId(long typeId, Pageable pageable); + Page findByTypeId(long typeId, Pageable pageable); @Query( "select ab.book " + "from AuthorsBooksEntity ab " + "where ab.author.id = ?1 " + - "order by ab.book.id" - ) + "order by ab.book.id") List findByAuthorId(Long authorId); @Query( "select ab.book " + "from AuthorsBooksEntity ab " + "where ab.author.id = ?1 " + - "order by ab.book.id" - ) - List findByAuthorId(Long authorId, Pageable pageable); + "order by ab.book.id") + Page findByAuthorId(Long authorId, Pageable pageable); @Query( "select ab.book " + "from AuthorsBooksEntity ab " + "where ab.author.id = ?1 and " + "ab.book.type.id = ?2 " + - "order by ab.book.id" - ) + "order by ab.book.id") List findByAuthorIdAndTypeId(Long authorId, Long typeId); @Query( @@ -49,9 +47,8 @@ public interface BookRepository extends "from AuthorsBooksEntity ab " + "where ab.author.id = ?1 and " + "ab.book.type.id = ?2 " + - "order by ab.book.id" - ) - List findByAuthorIdAndTypeId(Long authorId, Long typeId, Pageable pageable); + "order by ab.book.id") + Page findByAuthorIdAndTypeId(Long authorId, Long typeId, Pageable pageable); @Query( "select count(*) as number " + diff --git a/SpringApp/library/src/main/java/com/ip/library/books/service/BookService.java b/SpringApp/library/src/main/java/com/ip/library/books/service/BookService.java index 610bdfd..e893c19 100644 --- a/SpringApp/library/src/main/java/com/ip/library/books/service/BookService.java +++ b/SpringApp/library/src/main/java/com/ip/library/books/service/BookService.java @@ -3,6 +3,7 @@ package com.ip.library.books.service; import java.util.List; import java.util.stream.StreamSupport; +import org.springframework.data.domain.Page; import org.springframework.data.domain.PageRequest; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -37,11 +38,10 @@ public class BookService { } @Transactional(readOnly = true) - public List getAll(long typeId, long authorId, int page, int size) { + public Page getAll(long typeId, long authorId, int page, int size) { PageRequest pageRequest = PageRequest.of(page, size); if (typeId <= 0L && authorId <= 0L) - return StreamSupport.stream(repository.findAll(pageRequest).spliterator(), - false).toList(); + return repository.findAll(pageRequest); if (authorId <= 0L) return repository.findByTypeId(typeId, pageRequest); if (typeId <= 0L) @@ -49,6 +49,18 @@ public class BookService { return repository.findByAuthorIdAndTypeId(authorId, typeId, pageRequest); } + @Transactional(readOnly = true) + public List getAll(long typeId, long authorId) { + if (typeId <= 0L && authorId <= 0L) + return StreamSupport.stream(repository.findAll().spliterator(), + false).toList(); + if (authorId <= 0L) + return repository.findByTypeId(typeId); + if (typeId <= 0L) + return repository.findByAuthorId(authorId); + return repository.findByAuthorIdAndTypeId(authorId, typeId); + } + @Transactional(readOnly = true) public BookEntity get(long id) { return repository.findById(id) diff --git a/SpringApp/library/src/main/java/com/ip/library/users/repository/UserRepository.java b/SpringApp/library/src/main/java/com/ip/library/users/repository/UserRepository.java index 087947f..8c78de8 100644 --- a/SpringApp/library/src/main/java/com/ip/library/users/repository/UserRepository.java +++ b/SpringApp/library/src/main/java/com/ip/library/users/repository/UserRepository.java @@ -3,6 +3,7 @@ package com.ip.library.users.repository; import java.util.List; import java.util.Optional; +import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; import org.springframework.data.jpa.repository.Query; import org.springframework.data.repository.CrudRepository; @@ -28,5 +29,5 @@ public interface UserRepository extends "from FavoriteEntity f " + "where f.user.id = ?1 " + "order by f.book.id") - public List getUserFavorities(Long userId, Pageable pageable); + public Page getUserFavorities(Long userId, Pageable pageable); } diff --git a/SpringApp/library/src/main/java/com/ip/library/users/service/UserService.java b/SpringApp/library/src/main/java/com/ip/library/users/service/UserService.java index e8a6aba..1809381 100644 --- a/SpringApp/library/src/main/java/com/ip/library/users/service/UserService.java +++ b/SpringApp/library/src/main/java/com/ip/library/users/service/UserService.java @@ -103,7 +103,7 @@ public class UserService { } @Transactional(readOnly = true) - public List getUserFavorities (long userId, int page, int size) { + public Page getUserFavorities (long userId, int page, int size) { return repository.getUserFavorities(userId, PageRequest.of(page, size)); } } diff --git a/SpringApp/library/src/test/java/com/ip/library/BooksTests.java b/SpringApp/library/src/test/java/com/ip/library/BooksTests.java index a72ea75..98e79a2 100644 --- a/SpringApp/library/src/test/java/com/ip/library/BooksTests.java +++ b/SpringApp/library/src/test/java/com/ip/library/BooksTests.java @@ -1,7 +1,6 @@ package com.ip.library; import java.util.List; -import java.util.ArrayList; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.AfterEach; @@ -27,10 +26,11 @@ class BooksTests { private TypeService typeService; @Autowired private AuthorService authorService; - private BookEntity book; - private TypeEntity type; + private BookEntity book1; + private BookEntity book2; + private BookEntity book3; + private TypeEntity type1; private AuthorEntity author1; - private AuthorEntity author2; @AfterEach void removeData() { @@ -42,62 +42,63 @@ class BooksTests { @BeforeEach void createData() { removeData(); - type = typeService.create(new TypeEntity("type1")); + type1 = typeService.create(new TypeEntity("type1")); var type2 = typeService.create(new TypeEntity("type2")); author1 = authorService.create(new AuthorEntity("author1")); - author2 = authorService.create(new AuthorEntity("author2")); - List list1 = new ArrayList<>(); - list1.add(author1); - list1.add(author2); - bookService.create(new BookEntity("book1", type)); - bookService.create(new BookEntity("book2", type2)); - book = bookService.create(new BookEntity("book3", type)); + var author2 = authorService.create(new AuthorEntity("author2")); + book1 = bookService.create(new BookEntity("book1", type1)); + book2 = bookService.create(new BookEntity("book2", type1)); + book3 = bookService.create(new BookEntity("book3", type2)); + bookService.addAuthor(author1.getId(), book1.getId()); + bookService.addAuthor(author1.getId(), book3.getId()); + bookService.addAuthor(author2.getId(), book1.getId()); + bookService.addAuthor(author2.getId(), book2.getId()); } @Test void createTest() { Assertions.assertEquals(3, bookService.getAll().size()); - Assertions.assertEquals("book3", book.getName()); - Assertions.assertEquals(type, book.getType()); - Assertions.assertEquals(0, bookService.getBookSubscribersNumber(book.getId())); + Assertions.assertEquals("book1", book1.getName()); + Assertions.assertEquals(type1, book1.getType()); + Assertions.assertEquals(0, bookService.getBookSubscribersNumber(book1.getId())); } @Test void getTest() { - Assertions.assertEquals(book, bookService.get(book.getId())); + Assertions.assertEquals(book1, bookService.get(book1.getId())); Assertions.assertThrows(NotFoundException.class, () -> bookService.get(0L)); } @Test void updateTest() { - final String testName = book.getName() + "TEST"; + final String testName = book1.getName() + "TEST"; final TypeEntity testType = typeService.create( - new TypeEntity(book.getType().getName() + "TEST")); - book = bookService.update(book.getId(), new BookEntity(testName, testType)); + new TypeEntity(book1.getType().getName() + "TEST")); + book1 = bookService.update(book1.getId(), new BookEntity(testName, testType)); Assertions.assertEquals(3, bookService.getAll().size()); - Assertions.assertEquals(testName, book.getName()); - Assertions.assertEquals(testType, book.getType()); + Assertions.assertEquals(testName, book1.getName()); + Assertions.assertEquals(testType, book1.getType()); } @Test void deleteTest() { - bookService.delete(book.getId()); + bookService.delete(book1.getId()); Assertions.assertEquals(2, bookService.getAll().size()); final BookEntity newEntity = bookService.create( - new BookEntity(book.getName(), book.getType())); + new BookEntity(book1.getName(), book1.getType())); Assertions.assertEquals(3, bookService.getAll().size()); - Assertions.assertNotEquals(book.getId(), newEntity.getId()); + Assertions.assertNotEquals(book1.getId(), newEntity.getId()); } @Test void nullNameTest() { Assertions.assertThrows( DataIntegrityViolationException.class, - () -> bookService.create(new BookEntity(null, book.getType())) + () -> bookService.create(new BookEntity(null, book1.getType())) ); Assertions.assertThrows( DataIntegrityViolationException.class, - () -> bookService.update(book.getId(), new BookEntity(null, book.getType())) + () -> bookService.update(book1.getId(), new BookEntity(null, book1.getType())) ); } @@ -105,11 +106,11 @@ class BooksTests { void nullTypeTest() { Assertions.assertThrows( DataIntegrityViolationException.class, - () -> bookService.create(new BookEntity(book.getName() + "TEST", null)) + () -> bookService.create(new BookEntity(book1.getName() + "TEST", null)) ); Assertions.assertThrows( DataIntegrityViolationException.class, - () -> bookService.update(book.getId(), new BookEntity(book.getName() + "TEST", null)) + () -> bookService.update(book1.getId(), new BookEntity(book1.getName() + "TEST", null)) ); } @@ -117,11 +118,27 @@ class BooksTests { void uniqueNameTest() { Assertions.assertThrows( IllegalArgumentException.class, - () -> bookService.create(new BookEntity(book.getName(), book.getType())) + () -> bookService.create(new BookEntity(book1.getName(), book1.getType())) ); Assertions.assertThrows( IllegalArgumentException.class, - () -> bookService.update(book.getId(), new BookEntity(book.getName(), book.getType())) + () -> bookService.update(book1.getId(), new BookEntity(book1.getName(), book1.getType())) ); } + + @Test + void getByFilterTest() { + //filter by type + List list = bookService.getAll(type1.getId(), -1L); + Assertions.assertEquals(2, list.size()); + Assertions.assertTrue(list.contains(book1) && list.contains(book2)); + //filter by author + list = bookService.getAll(-1L, author1.getId()); + Assertions.assertEquals(2, list.size()); + Assertions.assertTrue(list.contains(book1) && list.contains(book3)); + //filter by type and author + list = bookService.getAll(type1.getId(), author1.getId()); + Assertions.assertEquals(1, list.size()); + Assertions.assertTrue(list.contains(book1)); + } } diff --git a/SpringApp/library/src/test/java/com/ip/library/FavoritesTests.java b/SpringApp/library/src/test/java/com/ip/library/FavoritesTests.java index 65140f1..f3427cf 100644 --- a/SpringApp/library/src/test/java/com/ip/library/FavoritesTests.java +++ b/SpringApp/library/src/test/java/com/ip/library/FavoritesTests.java @@ -1,5 +1,7 @@ package com.ip.library; +import java.util.List; + import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.BeforeEach; @@ -22,15 +24,16 @@ class FavoritesTests { private UserService userService; @Autowired private TypeService typeService; - private UserEntity user; + private UserEntity user1; + private UserEntity user2; private BookEntity book1; private BookEntity book2; @AfterEach void removeData() { + userService.getAll().forEach(item -> userService.delete(item.getId())); bookService.getAll().forEach(item -> bookService.delete(item.getId())); typeService.getAll().forEach(item -> typeService.delete(item.getId())); - userService.getAll().forEach(item -> userService.delete(item.getId())); } @BeforeEach @@ -39,15 +42,25 @@ class FavoritesTests { TypeEntity type = typeService.create(new TypeEntity("type1")); book1 = bookService.create(new BookEntity("book1", type)); book2 = bookService.create(new BookEntity("book2", type)); - userService.create(new UserEntity("user1", "123")); + user1 = userService.create(new UserEntity("user3", "aqw2sed45")); + user2 = userService.create(new UserEntity("user1", "123")); userService.create(new UserEntity("user2", "456")); - user = userService.create(new UserEntity("user3", "aqw2sed45")); + userService.addFavorite(user1.getId(), book2.getId()); + userService.addFavorite(user2.getId(), book1.getId()); + userService.addFavorite(user2.getId(), book2.getId()); } @Test - void favoritesTest() { - Assertions.assertEquals(0, userService.getUserFavorities(user.getId()).size()); - Assertions.assertEquals(0, bookService.getBookSubscribersNumber(book1.getId())); - Assertions.assertEquals(0, bookService.getBookSubscribersNumber(book2.getId())); + void getBookSubscribersNumberTest() { + Assertions.assertEquals(1, bookService.getBookSubscribersNumber(book1.getId())); + Assertions.assertEquals(2, bookService.getBookSubscribersNumber(book2.getId())); + } + + @Test + void getUserFavoritiesTest() { + List list = userService.getUserFavorities(user2.getId()); + Assertions.assertEquals(2, list.size()); + Assertions.assertTrue(list.contains(book1)); + Assertions.assertTrue(list.contains(book2)); } } -- 2.25.1