diff --git a/demo/src/main/java/com/example/demo/core/config/Constants.java b/demo/src/main/java/com/example/demo/core/config/Constants.java index c62b4c9..454f0de 100644 --- a/demo/src/main/java/com/example/demo/core/config/Constants.java +++ b/demo/src/main/java/com/example/demo/core/config/Constants.java @@ -1,5 +1,6 @@ package com.example.demo.core.config; public class Constants { + public static final String SEQUENCE_NAME = "hibernate_sequence"; public static final String API_URL = "/api_3"; } diff --git a/demo/src/main/java/com/example/demo/core/error/NotFoundException.java b/demo/src/main/java/com/example/demo/core/error/NotFoundException.java index 64cb700..eac0fa7 100644 --- a/demo/src/main/java/com/example/demo/core/error/NotFoundException.java +++ b/demo/src/main/java/com/example/demo/core/error/NotFoundException.java @@ -1,7 +1,7 @@ package com.example.demo.core.error; public class NotFoundException extends RuntimeException { - public NotFoundException(long id) { - super(String.format("Entity with id {%s} is not found or not exists", id)); + public NotFoundException(Class clazz, Long id) { + super(String.format("%s with id [%s] is not found or not exists", clazz.getSimpleName(), id)); } } diff --git a/demo/src/main/java/com/example/demo/core/model/BaseEntity.java b/demo/src/main/java/com/example/demo/core/model/BaseEntity.java index 400bb42..ca02c45 100644 --- a/demo/src/main/java/com/example/demo/core/model/BaseEntity.java +++ b/demo/src/main/java/com/example/demo/core/model/BaseEntity.java @@ -1,19 +1,28 @@ package com.example.demo.core.model; +import com.example.demo.core.config.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; + protected BaseEntity() { } - public Long getId(){ + public Long getId() { return id; } - public void setId(Long id){ + + public void setId(Long id) { this.id = id; } -} +} \ No newline at end of file diff --git a/demo/src/main/java/com/example/demo/core/repository/CommonRepository.java b/demo/src/main/java/com/example/demo/core/repository/CommonRepository.java deleted file mode 100644 index b5f11f9..0000000 --- a/demo/src/main/java/com/example/demo/core/repository/CommonRepository.java +++ /dev/null @@ -1,12 +0,0 @@ -package com.example.demo.core.repository; - -import java.util.List; - -public interface CommonRepository { - List getAll(); - E get(T id); - E create(E entity); - E update(E entity); - E delete(E entity); - void deleteAll(); -} diff --git a/demo/src/main/java/com/example/demo/core/repository/MapRepository.java b/demo/src/main/java/com/example/demo/core/repository/MapRepository.java deleted file mode 100644 index 3b4726b..0000000 --- a/demo/src/main/java/com/example/demo/core/repository/MapRepository.java +++ /dev/null @@ -1,56 +0,0 @@ -package com.example.demo.core.repository; - -import com.example.demo.core.model.BaseEntity; - -import java.util.List; -import java.util.Map; -import java.util.TreeMap; - -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){ - 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(){ - long count = lastId; - lastId = 0L; - entities.clear(); - } -} diff --git a/demo/src/main/java/com/example/demo/games/model/GameEntity.java b/demo/src/main/java/com/example/demo/games/model/GameEntity.java index a77ba75..8d364fb 100644 --- a/demo/src/main/java/com/example/demo/games/model/GameEntity.java +++ b/demo/src/main/java/com/example/demo/games/model/GameEntity.java @@ -1,18 +1,29 @@ package com.example.demo.games.model; import com.example.demo.core.model.BaseEntity; +import com.example.demo.tables.model.BookingEntity; +import com.example.demo.users.model.UserEntity; +import jakarta.persistence.*; -import java.util.Date; +import java.util.List; +@Entity +@Table(name = "game") public class GameEntity extends BaseEntity { + @Column(nullable = false, unique = true, length = 100) private String name; + @ManyToMany(mappedBy = "user_game") + private List users; + + @OneToMany(mappedBy = "game", cascade = CascadeType.ALL, orphanRemoval = true) + @OrderBy("date desc") + List bookings; + public GameEntity() { - super(); } - public GameEntity(Long id, String name) { - super(id); + public GameEntity(String name) { this.name = name; } @@ -22,4 +33,12 @@ public class GameEntity extends BaseEntity { public void setName(String name){ this.name = name; } + + public List getUsers(){ + return users; + } + + public List getBookings(){ + return bookings; + } } diff --git a/demo/src/main/java/com/example/demo/games/service/GameService.java b/demo/src/main/java/com/example/demo/games/service/GameService.java index 1549b86..91d14d7 100644 --- a/demo/src/main/java/com/example/demo/games/service/GameService.java +++ b/demo/src/main/java/com/example/demo/games/service/GameService.java @@ -19,7 +19,7 @@ public class GameService { } public List getAll(){ - return repository.getAll(); + return repository.findAll(); } public GameEntity get(long id){ diff --git a/demo/src/main/java/com/example/demo/tables/api/TableController.java b/demo/src/main/java/com/example/demo/tables/api/TableController.java index e3c9099..a61c40b 100644 --- a/demo/src/main/java/com/example/demo/tables/api/TableController.java +++ b/demo/src/main/java/com/example/demo/tables/api/TableController.java @@ -3,7 +3,7 @@ package com.example.demo.tables.api; import com.example.demo.core.config.Constants; import com.example.demo.games.api.GameDTO; import com.example.demo.games.model.GameEntity; -import com.example.demo.tables.model.TableEntity; +import com.example.demo.tables.model.BookingEntity; import com.example.demo.tables.service.TableService; import com.example.demo.users.api.UserDTO; import com.example.demo.users.model.UserEntity; @@ -25,7 +25,7 @@ public class TableController { this.modelMapper = modelMapper; } - private TableDTO toDTO(TableEntity entity) { + private TableDTO toDTO(BookingEntity entity) { return new TableDTO( entity.getId(), entity.getDescription(), @@ -35,8 +35,8 @@ public class TableController { entity.getGamers().stream().map(e -> modelMapper.map(e, UserDTO.class)).toList() ); } - private TableEntity toEntity(TableDTO dto){ - TableEntity entity = modelMapper.map(dto, TableEntity.class); + private BookingEntity toEntity(TableDTO dto){ + BookingEntity entity = modelMapper.map(dto, BookingEntity.class); entity.setCreator(modelMapper.map(dto.getCreator(), UserEntity.class)); entity.setGame(modelMapper.map(dto.getGame(), GameEntity.class)); entity.setGamers(dto.getGamers().stream() diff --git a/demo/src/main/java/com/example/demo/tables/model/TableEntity.java b/demo/src/main/java/com/example/demo/tables/model/BookingEntity.java similarity index 67% rename from demo/src/main/java/com/example/demo/tables/model/TableEntity.java rename to demo/src/main/java/com/example/demo/tables/model/BookingEntity.java index 90d19de..3503699 100644 --- a/demo/src/main/java/com/example/demo/tables/model/TableEntity.java +++ b/demo/src/main/java/com/example/demo/tables/model/BookingEntity.java @@ -3,22 +3,36 @@ package com.example.demo.tables.model; import com.example.demo.core.model.BaseEntity; import com.example.demo.games.model.GameEntity; import com.example.demo.users.model.UserEntity; +import jakarta.persistence.*; import java.util.Date; import java.util.List; -public class TableEntity extends BaseEntity { +@Entity +@Table(name = "booking") +public class BookingEntity extends BaseEntity { + @Column(nullable = false, length = 500) private String description; - private Date date; - private UserEntity creator; - private GameEntity game; - private List gamers; - public TableEntity() { - super(); + @Column(nullable = false) + private Date date; + + @ManyToOne + @JoinColumn(name = "creator_id") + private UserEntity creator; + + @ManyToOne + @JoinColumn(name = "game_id") + private GameEntity game; + + @ManyToMany(mappedBy = "book_user") + private List users; + + public BookingEntity() { + } - public TableEntity(String description, Date date, - UserEntity creator, GameEntity game, List users){ + public BookingEntity(String description, + Date date){ this.description = description; this.date = date; } @@ -52,9 +66,9 @@ public class TableEntity extends BaseEntity { } public List getGamers(){ - return gamers; + return users; } public void setGamers(List gamers){ - this.gamers = gamers; + this.users = gamers; } } diff --git a/demo/src/main/java/com/example/demo/tables/repository/TableRepository.java b/demo/src/main/java/com/example/demo/tables/repository/TableRepository.java index 6d7bfa9..8394aa2 100644 --- a/demo/src/main/java/com/example/demo/tables/repository/TableRepository.java +++ b/demo/src/main/java/com/example/demo/tables/repository/TableRepository.java @@ -1,8 +1,8 @@ package com.example.demo.tables.repository; -import com.example.demo.tables.model.TableEntity; +import com.example.demo.tables.model.BookingEntity; import org.springframework.data.repository.CrudRepository; -public interface TableRepository extends CrudRepository { +public interface TableRepository extends CrudRepository { } diff --git a/demo/src/main/java/com/example/demo/tables/service/TableService.java b/demo/src/main/java/com/example/demo/tables/service/TableService.java index a5b68cc..634393e 100644 --- a/demo/src/main/java/com/example/demo/tables/service/TableService.java +++ b/demo/src/main/java/com/example/demo/tables/service/TableService.java @@ -2,14 +2,11 @@ package com.example.demo.tables.service; import com.example.demo.core.error.NotFoundException; import com.example.demo.games.service.GameService; -import com.example.demo.tables.model.TableEntity; +import com.example.demo.tables.model.BookingEntity; import com.example.demo.tables.repository.TableRepository; -import com.example.demo.users.model.UserEntity; import com.example.demo.users.service.UserService; -import jakarta.validation.OverridesAttribute; import org.springframework.stereotype.Service; -import java.util.Date; import java.util.List; import java.util.Optional; @@ -25,16 +22,16 @@ public class TableService { this.gameService = gameService; } - public List getAll(){ + public List getAll(){ return repository.getAll(); } - public TableEntity get(Long id){ + public BookingEntity get(Long id){ return Optional .ofNullable(repository.get(id)) .orElseThrow(() -> new NotFoundException(id)); } - public TableEntity create(TableEntity entity){ + public BookingEntity create(BookingEntity entity){ entity.setCreator( entity.getCreator() == null ? entity.getCreator() : @@ -55,8 +52,8 @@ public class TableService { return repository.create(entity); } - public TableEntity update(Long id, TableEntity entity){ - final TableEntity existEntity = get(id); + public BookingEntity update(Long id, BookingEntity entity){ + final BookingEntity existEntity = get(id); existEntity.setDate(entity.getDate() == null ? existEntity.getDate() : entity.getDate()); existEntity.setDescription( @@ -84,7 +81,7 @@ public class TableService { return repository.update(existEntity); } - public TableEntity delete(Long id){ + public BookingEntity delete(Long id){ return repository.delete(repository.get(id)); } } diff --git a/demo/src/main/java/com/example/demo/users/api/UserController.java b/demo/src/main/java/com/example/demo/users/api/UserController.java index f8c9f72..6a85d35 100644 --- a/demo/src/main/java/com/example/demo/users/api/UserController.java +++ b/demo/src/main/java/com/example/demo/users/api/UserController.java @@ -7,14 +7,7 @@ import com.example.demo.users.model.UserEntity; import com.example.demo.users.service.UserService; import jakarta.validation.Valid; 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.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.RestController; +import org.springframework.web.bind.annotation.*; @RestController @RequestMapping(Constants.API_URL + "/users") @@ -43,7 +36,10 @@ public class UserController { @GetMapping public List getAll() { - return userService.getAll().stream().map(this::toDTO).toList(); + return userService.getAll() + .stream() + .map(this::toDTO) + .toList(); } @GetMapping("/{id}") @@ -52,13 +48,15 @@ public class UserController { return toDTO(userService.get(id)); } - @PostMapping("/") + @PostMapping public UserDTO create(@RequestBody @Valid UserDTO dto) { return toDTO(userService.create(toEntity(dto))); } @PutMapping("/{id}") - public UserDTO update(@PathVariable(name = "id") long id, @RequestBody UserDTO dto) { + public UserDTO update( + @PathVariable(name = "id") long id, + @RequestBody UserDTO dto) { return toDTO(userService.update(id, toEntity(dto))); } @@ -67,4 +65,36 @@ public class UserController { { return toDTO(userService.delete(id)); } + + @GetMapping("/{id}/subscription") + public List getUserSubscriptions(@PathVariable(name = "id") Long id) { + return userService.getUserSubscriptions(id).stream() + .map(this::toSubscriptionDto) + .toList(); + } + + @PostMapping("/{id}/subscription") + public List enableUserSubscriptions( + @PathVariable(name = "id") Long id, + @RequestParam(name = "subscriptions", defaultValue = "") List subscriptionsIds) { + return userService.enableUserSubscriptions(id, subscriptionsIds).stream() + .map(this::toSubscriptionDto) + .toList(); + } + + @DeleteMapping("/{id}/subscription") + public List disableUserSubscriptions( + @PathVariable(name = "id") Long id, + @RequestParam(name = "subscriptions", defaultValue = "") List subscriptionsIds) { + return userService.disableUserSubscriptions(id, subscriptionsIds).stream() + .map(this::toSubscriptionDto) + .toList(); + } + + @DeleteMapping("/{id}/subscription/all") + public List deleteAllUserSubscriptions(@PathVariable(name = "id") Long id) { + return userService.deleteAllUserSubscriptions(id).stream() + .map(this::toSubscriptionDto) + .toList(); + } } diff --git a/demo/src/main/java/com/example/demo/users/api/UserDTO.java b/demo/src/main/java/com/example/demo/users/api/UserDTO.java index 5c5745e..a7fcfb4 100644 --- a/demo/src/main/java/com/example/demo/users/api/UserDTO.java +++ b/demo/src/main/java/com/example/demo/users/api/UserDTO.java @@ -1,6 +1,5 @@ package com.example.demo.users.api; -import com.fasterxml.jackson.annotation.JsonProperty; import jakarta.validation.constraints.*; public class UserDTO { @@ -8,12 +7,9 @@ public class UserDTO { @NotNull @Min(2) private String name; - @NotNull + @NotBlank @Min(4) private String login; - @NotNull - @Min(4) - private String password; public String getName() { return name; @@ -28,12 +24,6 @@ public class UserDTO { public void setLogin(String login){ this.login = login; } - public String getPassword() { - return password; - } - public void setPassword(String password){ - this.password = password; - } public Long getId(){ return id; } diff --git a/demo/src/main/java/com/example/demo/users/model/UserEntity.java b/demo/src/main/java/com/example/demo/users/model/UserEntity.java index ac977ee..06cb483 100644 --- a/demo/src/main/java/com/example/demo/users/model/UserEntity.java +++ b/demo/src/main/java/com/example/demo/users/model/UserEntity.java @@ -1,33 +1,26 @@ package com.example.demo.users.model; import com.example.demo.core.model.BaseEntity; +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.Table; import java.util.Date; +@Entity +@Table(name = "users") public class UserEntity extends BaseEntity { + @Column(nullable = false, unique = true, length = 100) private String name; + @Column(nullable = false, unique = true, length = 50) private String login; - private String password; - private Date dateCreate; - public UserEntity() { - super(); + } - public UserEntity(Long id, String name, String login, String password) { - super(id); - this.name = name; + public UserEntity(String login, String name) { this.login = login; - this.password = password; - this.dateCreate = new Date(); - } - - public UserEntity(Long id, String name) { - super(id); this.name = name; - this.dateCreate = new Date(); - this.login = ""; - this.password = ""; } public String getName(){ @@ -44,17 +37,4 @@ public class UserEntity extends BaseEntity { this.login = login; } - public String getPassword(){ - return password; - } - public void setPassword(String password){ - this.password = password; - } - - public Date getDateCreate(){ - return dateCreate; - } - public void setDateCreate(Date dateCreate){ - this.dateCreate = dateCreate; - } } diff --git a/demo/src/main/java/com/example/demo/users/repository/UserRepository.java b/demo/src/main/java/com/example/demo/users/repository/UserRepository.java index 49d2fd9..748f6a6 100644 --- a/demo/src/main/java/com/example/demo/users/repository/UserRepository.java +++ b/demo/src/main/java/com/example/demo/users/repository/UserRepository.java @@ -2,6 +2,9 @@ package com.example.demo.users.repository; import com.example.demo.users.model.UserEntity; import org.springframework.data.repository.CrudRepository; -public interface UserRepository extends CrudRepository { +import java.util.Optional; + +public interface UserRepository extends CrudRepository { + Optional findByLoginIgnoreCase(String login); } diff --git a/demo/src/main/java/com/example/demo/users/service/UserService.java b/demo/src/main/java/com/example/demo/users/service/UserService.java index 446e59d..338dafe 100644 --- a/demo/src/main/java/com/example/demo/users/service/UserService.java +++ b/demo/src/main/java/com/example/demo/users/service/UserService.java @@ -4,11 +4,13 @@ import com.example.demo.core.error.NotFoundException; import com.example.demo.users.model.UserEntity; import com.example.demo.users.repository.UserRepository; import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; import java.awt.event.ItemEvent; import java.util.List; import java.util.Objects; import java.util.Optional; +import java.util.stream.StreamSupport; @Service public class UserService { @@ -17,8 +19,16 @@ public class UserService { this.repository = repository; } - public List getAll(){ - return repository.getAll(); + private void checkLogin(String login) { + if (repository.findByLoginIgnoreCase(login).isPresent()) { + throw new IllegalArgumentException( + String.format("User with login %s is already exists", login)); + } + } + + @Transactional(readOnly = true) + public List getAll() { + return StreamSupport.stream(repository.findAll().spliterator(), false).toList(); } public UserEntity get(Long id){ @@ -26,21 +36,29 @@ public class UserService { .ofNullable(repository.get(id)) .orElseThrow(() -> new NotFoundException(id)); } - public UserEntity create(UserEntity entity){ - return repository.create(entity); + @Transactional + public UserEntity create(UserEntity entity) { + if (entity == null) { + throw new IllegalArgumentException("Entity is null"); + } + checkLogin(entity.getLogin()); + repository.save(entity); + return repository.save(entity); } - public UserEntity update(Long id, UserEntity entity){ - final UserEntity existEntity = get(id); - - existEntity.setName(entity.getName().isEmpty() ? existEntity.getName() : entity.getName()); - existEntity.setLogin(entity.getLogin().isEmpty() ? existEntity.getLogin() : entity.getLogin()); - existEntity.setPassword(entity.getPassword().isEmpty() ? existEntity.getPassword() : entity.getPassword()); - - return repository.update(existEntity); + @Transactional + public UserEntity update(long id, UserEntity entity) { + final UserEntity existsEntity = get(id); + checkLogin(entity.getLogin()); + existsEntity.setLogin(entity.getLogin()); + repository.save(existsEntity); + return existsEntity; } - public UserEntity delete(Long id){ - return repository.delete(repository.get(id)); + @Transactional + public UserEntity delete(long id) { + final UserEntity existsEntity = get(id); + repository.delete(existsEntity); + return existsEntity; } }