всё переделано, тесты работают

This commit is contained in:
dex_moth 2024-05-04 18:26:03 +04:00
parent 66bfe560cd
commit f4337bb250
30 changed files with 577 additions and 210 deletions

3
.vscode/settings.json vendored Normal file
View File

@ -0,0 +1,3 @@
{
"java.configuration.updateBuildConfiguration": "interactive"
}

View File

@ -1,12 +1,23 @@
plugins { plugins {
id 'java' id 'java'
id 'org.springframework.boot' version '3.2.3' id 'org.springframework.boot' version '3.2.4'
id 'io.spring.dependency-management' version '1.1.4' id 'io.spring.dependency-management' version '1.1.4'
} }
group = 'com.example' group = 'com.example'
version = '0.0.1-SNAPSHOT' 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 { java {
sourceCompatibility = '17' sourceCompatibility = '17'
} }
@ -17,9 +28,13 @@ repositories {
dependencies { dependencies {
implementation 'org.springframework.boot:spring-boot-starter-web' 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.springdoc:springdoc-openapi-starter-webmvc-ui:2.3.0'
implementation 'org.modelmapper:modelmapper:3.2.0' implementation 'org.modelmapper:modelmapper:3.2.0'
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
implementation 'com.h2database:h2:2.2.224'
testImplementation 'org.springframework.boot:spring-boot-starter-test' testImplementation 'org.springframework.boot:spring-boot-starter-test'
} }

View File

@ -11,12 +11,13 @@ import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication; import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.autoconfigure.SpringBootApplication;
import com.example.demo.comment.model.CommentEntity; import com.example.demo.comments.model.CommentEntity;
import com.example.demo.comment.service.CommentService; import com.example.demo.comments.service.CommentService;
import com.example.demo.news.model.NewEntity; import com.example.demo.news.model.NewEntity;
import com.example.demo.news.service.NewService; import com.example.demo.news.service.NewService;
import com.example.demo.tage.model.TageEntity; import com.example.demo.newtage.model.NewTageEntity;
import com.example.demo.tage.service.TageService; import com.example.demo.tages.model.TageEntity;
import com.example.demo.tages.service.TageService;
import com.example.demo.users.model.UserEntity; import com.example.demo.users.model.UserEntity;
import com.example.demo.users.service.UserService; import com.example.demo.users.service.UserService;
@ -52,11 +53,13 @@ public class DemoApplication implements CommandLineRunner {
final var tage4 = tageService.create(new TageEntity(null, "программирование")); final var tage4 = tageService.create(new TageEntity(null, "программирование"));
// new // new
final NewEntity new1 = newService.create(new NewEntity(null, "Чемпионат ICPC", new Date(), Arrays.asList(tage1, tage2), final NewEntity new1 = newService.create(new NewEntity(null, "Чемпионат ICPC", new Date(),
"Студенты выступят на Чемпионате мира по программированию в Северной Евразии.")); "Студенты выступят на Чемпионате мира по программированию в Северной Евразии."));
final NewEntity new2 = newService.create(new NewEntity(null, "Новый год 2024", new Date(2024 - 1 - 01), Arrays.asList(tage3, tage4), final NewEntity new2 = newService.create(new NewEntity(null, "Новый год 2024", new Date(2024 - 1 - 01),
"Администрация ulstu поздравляет студентов и преподавателей с Новым годом и желает крепкого здоровья и успешного Года Дракона!")); "Администрация ulstu поздравляет студентов и преподавателей с Новым годом и желает крепкого здоровья и успешного Года Дракона!"));
final NewTageEntity newTage1 = new NewTageEntity(new1, tage1);
new1.addTage(newTage1);
// user // user
final var user1 = userService.create(new UserEntity(null, "beko", "111", "ddwwdd", final var user1 = userService.create(new UserEntity(null, "beko", "111", "ddwwdd",

View File

@ -1,10 +0,0 @@
package com.example.demo.comment.repository;
import org.springframework.stereotype.Repository;
import com.example.demo.comment.model.CommentEntity;
import com.example.demo.core.repository.MapRepository;
@Repository
public class CommentRepository extends MapRepository<CommentEntity> {
}

View File

@ -1,50 +0,0 @@
package com.example.demo.comment.service;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import org.springframework.stereotype.Service;
import com.example.demo.core.error.NotFoundException;
import com.example.demo.comment.model.CommentEntity;
import com.example.demo.comment.repository.CommentRepository;
@Service
public class CommentService {
private final CommentRepository repository;
public CommentService(CommentRepository repository) {
this.repository = repository;
}
public List<CommentEntity> getAll(Long newId) {
if (Objects.equals(newId, 0L)) {
return repository.getAll();
}
return repository.getAll().stream()
.filter(item -> item.getNew().getId().equals(newId))
.toList();
}
public CommentEntity get(Long id) {
return Optional.ofNullable(repository.get(id))
.orElseThrow(() -> new NotFoundException(id));
}
public CommentEntity create(CommentEntity entity) {
return repository.create(entity);
}
public CommentEntity update(Long id, CommentEntity entity) {
final CommentEntity existsEntity = get(id);
existsEntity.setDate(entity.getDate());
existsEntity.setText(entity.getText());
return repository.update(existsEntity);
}
public CommentEntity delete(Long id) {
final CommentEntity existsEntity = get(id);
return repository.delete(existsEntity);
}
}

View File

@ -1,4 +1,4 @@
package com.example.demo.comment.api; package com.example.demo.comments.api;
import java.util.List; import java.util.List;
@ -13,10 +13,10 @@ import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.RestController;
import com.example.demo.comments.model.CommentEntity;
import com.example.demo.comments.service.CommentService;
import com.example.demo.core.configuration.Constants; import com.example.demo.core.configuration.Constants;
import com.example.demo.news.service.NewService; import com.example.demo.news.service.NewService;
import com.example.demo.comment.model.CommentEntity;
import com.example.demo.comment.service.CommentService;
import jakarta.validation.Valid; import jakarta.validation.Valid;

View File

@ -1,9 +1,7 @@
package com.example.demo.comment.api; package com.example.demo.comments.api;
import java.util.Date; import java.util.Date;
import com.example.demo.news.model.NewEntity;
import com.example.demo.users.model.UserEntity;
import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonProperty;
import jakarta.validation.constraints.Min; import jakarta.validation.constraints.Min;

View File

@ -1,4 +1,4 @@
package com.example.demo.comment.model; package com.example.demo.comments.model;
import java.util.Date; import java.util.Date;
import java.util.Objects; import java.util.Objects;
@ -7,10 +7,24 @@ import com.example.demo.core.model.BaseEntity;
import com.example.demo.news.model.NewEntity; import com.example.demo.news.model.NewEntity;
import com.example.demo.users.model.UserEntity; import com.example.demo.users.model.UserEntity;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.JoinColumn;
import jakarta.persistence.ManyToOne;
import jakarta.persistence.Table;
@Entity
@Table(name = "comments")
public class CommentEntity extends BaseEntity { public class CommentEntity extends BaseEntity {
@Column(nullable = false)
private Date date; private Date date;
@Column(nullable = false, length = 200)
private String text; private String text;
@ManyToOne
@JoinColumn(name = "newsId", nullable = false)
private NewEntity news; private NewEntity news;
@ManyToOne
@JoinColumn(name = "userId", nullable = false)
private UserEntity user; private UserEntity user;
public CommentEntity() { public CommentEntity() {
@ -43,6 +57,9 @@ public class CommentEntity extends BaseEntity {
public void setNew(NewEntity news) { public void setNew(NewEntity news) {
this.news = news; this.news = news;
if (!news.getComments().contains(this)) {
news.getComments().add(this);
}
} }
public NewEntity getNew() { public NewEntity getNew() {
@ -51,6 +68,9 @@ public class CommentEntity extends BaseEntity {
public void setUser(UserEntity user) { public void setUser(UserEntity user) {
this.user = user; this.user = user;
if (!user.getComments().contains(this)) {
user.getComments().add(this);
}
} }
public UserEntity getUser() { public UserEntity getUser() {

View File

@ -0,0 +1,8 @@
package com.example.demo.comments.repository;
import org.springframework.data.repository.CrudRepository;
import com.example.demo.comments.model.CommentEntity;
public interface CommentRepository extends CrudRepository<CommentEntity, Long> {
}

View File

@ -0,0 +1,60 @@
package com.example.demo.comments.service;
import java.util.List;
import java.util.Objects;
import java.util.stream.StreamSupport;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.example.demo.comments.model.CommentEntity;
import com.example.demo.comments.repository.CommentRepository;
import com.example.demo.core.error.NotFoundException;
@Service
public class CommentService {
private final CommentRepository repository;
public CommentService(CommentRepository repository) {
this.repository = repository;
}
@Transactional(readOnly = true)
public List<CommentEntity> getAll(Long newId) {
if (Objects.equals(newId, 0L)) {
return StreamSupport.stream(repository.findAll().spliterator(), false).toList();
}
return StreamSupport.stream(repository.findAll().spliterator(), false)
.filter(item -> item.getNew().getId().equals(newId))
.toList();
}
@Transactional(readOnly = true)
public CommentEntity get(Long id) {
return repository.findById(id)
.orElseThrow(() -> new NotFoundException(CommentEntity.class, id));
}
@Transactional
public CommentEntity create(CommentEntity entity) {
if (entity == null) {
throw new IllegalArgumentException("Entity is null");
}
return repository.save(entity);
}
@Transactional
public CommentEntity update(Long id, CommentEntity entity) {
final CommentEntity existsEntity = get(id);
existsEntity.setDate(entity.getDate());
existsEntity.setText(entity.getText());
return repository.save(entity);
}
@Transactional
public CommentEntity delete(Long id) {
final CommentEntity existsEntity = get(id);
repository.delete(existsEntity);
return existsEntity;
}
}

View File

@ -1,7 +1,7 @@
package com.example.demo.core.error; package com.example.demo.core.error;
public class NotFoundException extends RuntimeException { public class NotFoundException extends RuntimeException {
public NotFoundException(Long id) { public <T> NotFoundException(Class<T> clazz, Long id) {
super(String.format("Entity with id [%s] is not found or not exists", id)); super(String.format("%s with id [%s] is not found or not exists", clazz.getSimpleName(), id));
} }
} }

View File

@ -18,8 +18,9 @@ import org.springframework.web.bind.annotation.RestController;
import com.example.demo.core.configuration.Constants; import com.example.demo.core.configuration.Constants;
import com.example.demo.news.model.NewEntity; import com.example.demo.news.model.NewEntity;
import com.example.demo.news.service.NewService; import com.example.demo.news.service.NewService;
import com.example.demo.tage.model.TageEntity; import com.example.demo.tages.api.TageDto;
import com.example.demo.tage.service.TageService; import com.example.demo.tages.model.TageEntity;
import com.example.demo.tages.service.TageService;
import jakarta.validation.Valid; import jakarta.validation.Valid;
@ -27,29 +28,23 @@ import jakarta.validation.Valid;
@RequestMapping(Constants.API_URL + "/new") @RequestMapping(Constants.API_URL + "/new")
public class NewController { public class NewController {
private final NewService newService; private final NewService newService;
private final TageService tageService;
private final ModelMapper modelMapper; private final ModelMapper modelMapper;
public NewController(NewService newService, TageService tageService, ModelMapper modelMapper) { public NewController(NewService newService, ModelMapper modelMapper) {
this.newService = newService; this.newService = newService;
this.modelMapper = modelMapper; this.modelMapper = modelMapper;
this.tageService = tageService;
} }
private NewDto toDto(NewEntity entity) { private NewDto toDto(NewEntity entity) {
return modelMapper.map(entity, NewDto.class); return modelMapper.map(entity, NewDto.class);
} }
private NewEntity toEntity(NewDto dto) { private NewDto toTageDto(TageEntity entity) {
final var entity = modelMapper.map(dto, NewEntity.class); return modelMapper.map(entity, NewDto.class);
List<Long> tagesId = dto.getTagesId();
List<TageEntity> tages = Arrays.asList();
for (var tageId : tagesId)
{
tages.add(tageService.get(tageId));
} }
entity.setTage(tages);
return entity; private NewEntity toEntity(NewDto dto) {
return modelMapper.map(dto, NewEntity.class);
} }
@GetMapping @GetMapping
@ -68,7 +63,7 @@ public class NewController {
} }
@PutMapping("/{id}") @PutMapping("/{id}")
public NewDto update(@PathVariable(name = "id") Long id, @RequestBody NewDto dto) { public NewDto update(@PathVariable(name = "id") Long id, @RequestBody @Valid NewDto dto) {
return toDto(newService.update(id, toEntity(dto))); return toDto(newService.update(id, toEntity(dto)));
} }
@ -76,4 +71,36 @@ public class NewController {
public NewDto delete(@PathVariable(name = "id") Long id) { public NewDto delete(@PathVariable(name = "id") Long id) {
return toDto(newService.delete(id)); return toDto(newService.delete(id));
} }
@GetMapping("/{id}/tage")
public List<TageDto> getNewTages(@PathVariable(name = "id") Long id) {
return newService.getNewTages(id).stream()
.map(this::toTageDto)
.toList();
}
@PostMapping("/{id}/tage")
public List<TageDto> enableNewTages(
@PathVariable(name = "id") Long id,
@RequestParam(name = "tages", defaultValue = "") List<Long> tagesIds) {
return newService.enableNewTages(id, tagesIds).stream()
.map(this::toTageDto)
.toList();
}
@DeleteMapping("/{id}/tage")
public List<TageDto> disableNewTages(
@PathVariable(name = "id") Long id,
@RequestParam(name = "tages", defaultValue = "") List<Long> tagesIds) {
return newService.disableNewTages(id, tagesIds).stream()
.map(this::toTageDto)
.toList();
}
@DeleteMapping("/{id}/tage/all")
public List<TageDto> deleteAllNewTages(@PathVariable(name = "id") Long id) {
return newService.deleteAllNewTages(id).stream()
.map(this::toTageDto)
.toList();
}
} }

View File

@ -1,27 +1,45 @@
package com.example.demo.news.model; package com.example.demo.news.model;
import java.util.Date; import java.util.Date;
import java.util.List; import java.util.HashSet;
import java.util.Objects; import java.util.Objects;
import java.util.Set;
import com.example.demo.comments.model.CommentEntity;
import com.example.demo.core.model.BaseEntity; import com.example.demo.core.model.BaseEntity;
import com.example.demo.tage.model.TageEntity; import com.example.demo.newtage.model.NewTageEntity;
import jakarta.persistence.CascadeType;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.OneToMany;
import jakarta.persistence.OrderBy;
import jakarta.persistence.Table;
@Entity
@Table(name = "news")
public class NewEntity extends BaseEntity { public class NewEntity extends BaseEntity {
@Column(nullable = false, length = 50)
private String title; private String title;
@Column(nullable = false)
private Date date; private Date date;
private List<TageEntity> tages; @Column(nullable = false, length = 150)
private String text; private String text;
@OneToMany(mappedBy = "new", cascade = CascadeType.ALL)
@OrderBy("id ASC")
private Set<NewTageEntity> newTages = new HashSet<>();
@OneToMany(mappedBy = "new", cascade = CascadeType.ALL)
@OrderBy("id ASC")
private Set<CommentEntity> comments = new HashSet<>();
public NewEntity() { public NewEntity() {
super(); super();
} }
public NewEntity(Long id, String title, Date date, List<TageEntity> tages, String text) { public NewEntity(Long id, String title, Date date, String text) {
super(id); super(id);
this.title = title; this.title = title;
this.date = date; this.date = date;
this.tages = tages;
this.text = text; this.text = text;
} }
@ -41,14 +59,6 @@ public class NewEntity extends BaseEntity {
this.date = date; this.date = date;
} }
public List<TageEntity> getTage() {
return tages;
}
public void setTage(List<TageEntity> tages) {
this.tages = tages;
}
public String getText() { public String getText() {
return text; return text;
} }
@ -57,9 +67,31 @@ public class NewEntity extends BaseEntity {
this.text = text; this.text = text;
} }
public Set<NewTageEntity> getNewTages() {
return newTages;
}
public void addTage(NewTageEntity newTage) {
if (newTage.getNew() != this) {
newTage.setNew(this);
}
newTages.add(newTage);
}
public void deleteTage(NewTageEntity newTage) {
if (newTage.getNew() != this) {
return;
}
newTages.remove(newTage);
}
public Set<CommentEntity> getComments() {
return comments;
}
@Override @Override
public int hashCode() { public int hashCode() {
return Objects.hash(id, title, date, tages, text); return Objects.hash(id, title, date, newTages, text);
} }
@Override @Override
@ -72,7 +104,7 @@ public class NewEntity extends BaseEntity {
return Objects.equals(other.getId(), id) return Objects.equals(other.getId(), id)
&& Objects.equals(other.getTitle(), title) && Objects.equals(other.getTitle(), title)
&& Objects.equals(other.getDate(), date) && Objects.equals(other.getDate(), date)
&& Objects.equals(other.getTage(), tages) && Objects.equals(other.getNewTages(), newTages)
&& Objects.equals(other.getText(), text); && Objects.equals(other.getText(), text);
} }
} }

View File

@ -1,10 +1,8 @@
package com.example.demo.news.repository; package com.example.demo.news.repository;
import org.springframework.stereotype.Repository; import org.springframework.data.repository.CrudRepository;
import com.example.demo.core.repository.MapRepository;
import com.example.demo.news.model.NewEntity; import com.example.demo.news.model.NewEntity;
@Repository public interface NewRepository extends CrudRepository<NewEntity, Long> {
public class NewRepository extends MapRepository<NewEntity> {
} }

View File

@ -1,46 +1,87 @@
package com.example.demo.news.service; package com.example.demo.news.service;
import java.util.List; import java.util.List;
import java.util.Optional; import java.util.Objects;
import java.util.stream.StreamSupport;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.example.demo.core.error.NotFoundException; import com.example.demo.core.error.NotFoundException;
import com.example.demo.news.model.NewEntity; import com.example.demo.news.model.NewEntity;
import com.example.demo.news.repository.NewRepository; import com.example.demo.news.repository.NewRepository;
import com.example.demo.newtage.model.NewTageEntity;
import com.example.demo.tages.model.TageEntity;
import com.example.demo.tages.service.TageService;
@Service @Service
public class NewService { public class NewService {
private final NewRepository repository; private final NewRepository repository;
private final TageService tageService;
public NewService(NewRepository repository) { public NewService(NewRepository repository, TageService tageService) {
this.repository = repository; this.repository = repository;
this.tageService = tageService;
} }
@Transactional(readOnly = true)
public List<NewEntity> getAll() { public List<NewEntity> getAll() {
return repository.getAll(); return StreamSupport.stream(repository.findAll().spliterator(), false).toList();
} }
@Transactional(readOnly = true)
public NewEntity get(Long id) { public NewEntity get(Long id) {
return Optional.ofNullable(repository.get(id)) return repository.findById(id)
.orElseThrow(() -> new NotFoundException(id)); .orElseThrow(() -> new NotFoundException(NewEntity.class, id));
} }
@Transactional
public NewEntity create(NewEntity entity) { public NewEntity create(NewEntity entity) {
return repository.create(entity); if (entity == null) {
throw new IllegalArgumentException("Entity is null");
}
repository.save(entity);
tageService.getAll().forEach(tage -> {
final NewTageEntity userTage = new NewTageEntity(entity, tage);
userTage.setNew(entity);
userTage.setTage(tage);
});
return repository.save(entity);
} }
@Transactional
public NewEntity update(Long id, NewEntity entity) { public NewEntity update(Long id, NewEntity entity) {
final NewEntity existsEntity = get(id); final NewEntity existsEntity = get(id);
existsEntity.setTitle(entity.getTitle()); existsEntity.setTitle(entity.getTitle());
existsEntity.setDate(entity.getDate()); existsEntity.setDate(entity.getDate());
existsEntity.setTage(entity.getTage());
existsEntity.setText(entity.getText()); existsEntity.setText(entity.getText());
return repository.update(existsEntity); return repository.save(existsEntity);
} }
@Transactional
public NewEntity delete(Long id) { public NewEntity delete(Long id) {
final NewEntity existsEntity = get(id); final NewEntity existsEntity = get(id);
return repository.delete(existsEntity); repository.delete(existsEntity);
return existsEntity;
}
@Transactional(readOnly = true)
public List<TageEntity> getNewTages(long id) {
return get(id).getNewTages().stream()
.map(NewTageEntity::getTage)
.toList();
}
@Transactional
public List<TageEntity> deleteAllNewTages(long id) {
final NewEntity existsNew = get(id);
final List<NewTageEntity> tages = existsNew.getNewTages().stream()
.filter(tage -> Objects.nonNull(tage.getTage()))
.toList();
tages.forEach(existsNew::deleteTage);
repository.save(existsNew);
return tages.stream()
.map(NewTageEntity::getTage)
.toList();
} }
} }

View File

@ -0,0 +1,84 @@
package com.example.demo.newtage.model;
import java.util.Objects;
import com.example.demo.news.model.NewEntity;
import com.example.demo.tages.model.TageEntity;
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 = "news_tages")
public class NewTageEntity {
@EmbeddedId
private NewTageId id = new NewTageId();
@ManyToOne
@MapsId("newId")
@JoinColumn(name = "new_id")
private NewEntity news;
@ManyToOne
@MapsId("tageId")
@JoinColumn(name = "tage_id")
private TageEntity tage;
public NewTageEntity() {}
public NewTageEntity(NewEntity news, TageEntity tage) {
this.news = news;
this.tage = tage;
}
public NewTageId getId() {
return id;
}
public void setId(NewTageId id) {
this.id = id;
}
public NewEntity getNew() {
return news;
}
public void setNew(NewEntity news) {
this.news = news;
if (!news.getNewTages().contains(this)) {
news.getNewTages().add(this);
}
}
public TageEntity getTage() {
return tage;
}
public void setTage(TageEntity tage) {
this.tage = tage;
if (!tage.getNewTages().contains(this)) {
tage.getNewTages().add(this);
}
}
@Override
public int hashCode() {
return Objects.hash(id, news.getId(), tage.getId());
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null || getClass() != obj.getClass())
return false;
NewTageEntity other = (NewTageEntity) obj;
return Objects.equals(id, other.id)
&& Objects.equals(news.getId(), other.news.getId())
&& Objects.equals(tage.getId(), other.tage.getId());
}
}

View File

@ -0,0 +1,53 @@
package com.example.demo.newtage.model;
import java.util.Objects;
import java.util.Optional;
import jakarta.persistence.Embeddable;
@Embeddable
public class NewTageId {
private Long newId;
private Long tageId;
public NewTageId() {}
public NewTageId(Long newId, Long tageId) {
this.newId = newId;
this.tageId = tageId;
}
public Long getNewId() {
return newId;
}
public void setNewId(Long newId) {
this.newId = newId;
}
public Long getTageId() {
return tageId;
}
public void setTageId(Long tageId) {
this.tageId = tageId;
}
@Override
public int hashCode() {
return Objects.hash(
Optional.ofNullable(newId).orElse(0L),
Optional.ofNullable(tageId).orElse(0L));
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null || getClass() != obj.getClass())
return false;
NewTageId other = (NewTageId) obj;
return Objects.equals(newId, other.newId)
&& Objects.equals(tageId, other.tageId);
}
}

View File

@ -1,10 +0,0 @@
package com.example.demo.tage.repository;
import org.springframework.stereotype.Repository;
import com.example.demo.core.repository.MapRepository;
import com.example.demo.tage.model.TageEntity;
@Repository
public class TageRepository extends MapRepository<TageEntity> {
}

View File

@ -1,43 +0,0 @@
package com.example.demo.tage.service;
import java.util.List;
import java.util.Optional;
import org.springframework.stereotype.Service;
import com.example.demo.core.error.NotFoundException;
import com.example.demo.tage.model.TageEntity;
import com.example.demo.tage.repository.TageRepository;
@Service
public class TageService {
private final TageRepository repository;
public TageService(TageRepository repository) {
this.repository = repository;
}
public List<TageEntity> getAll() {
return repository.getAll();
}
public TageEntity get(Long id) {
return Optional.ofNullable(repository.get(id))
.orElseThrow(() -> new NotFoundException(id));
}
public TageEntity create(TageEntity entity) {
return repository.create(entity);
}
public TageEntity update(Long id, TageEntity entity) {
final TageEntity existsEntity = get(id);
existsEntity.setText(entity.getText());
return repository.update(existsEntity);
}
public TageEntity delete(Long id) {
final TageEntity existsEntity = get(id);
return repository.delete(existsEntity);
}
}

View File

@ -1,4 +1,4 @@
package com.example.demo.tage.api; package com.example.demo.tages.api;
import java.util.List; import java.util.List;
@ -13,8 +13,8 @@ import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.RestController;
import com.example.demo.core.configuration.Constants; import com.example.demo.core.configuration.Constants;
import com.example.demo.tage.model.TageEntity; import com.example.demo.tages.model.TageEntity;
import com.example.demo.tage.service.TageService; import com.example.demo.tages.service.TageService;
import jakarta.validation.Valid; import jakarta.validation.Valid;

View File

@ -1,4 +1,4 @@
package com.example.demo.tage.api; package com.example.demo.tages.api;
import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonProperty;

View File

@ -1,12 +1,28 @@
package com.example.demo.tage.model; package com.example.demo.tages.model;
import java.util.HashSet;
import java.util.Objects; import java.util.Objects;
import java.util.Set;
import com.example.demo.core.model.BaseEntity; import com.example.demo.core.model.BaseEntity;
import com.example.demo.news.model.NewEntity; import com.example.demo.news.model.NewEntity;
import com.example.demo.newtage.model.NewTageEntity;
import jakarta.persistence.CascadeType;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.OneToMany;
import jakarta.persistence.OrderBy;
import jakarta.persistence.Table;
@Entity
@Table(name = "tages")
public class TageEntity extends BaseEntity{ public class TageEntity extends BaseEntity{
@Column(nullable = false, unique = true, length = 50)
private String text; private String text;
@OneToMany(mappedBy = "tages", cascade = CascadeType.ALL)
@OrderBy("id ASC")
private Set<NewTageEntity> newTages = new HashSet<>();
public TageEntity() { public TageEntity() {
super(); super();
@ -30,6 +46,10 @@ public class TageEntity extends BaseEntity{
return Objects.hash(id, text); return Objects.hash(id, text);
} }
public Set<NewTageEntity> getNewTages() {
return newTages;
}
@Override @Override
public boolean equals(Object obj) { public boolean equals(Object obj) {
if (this == obj) if (this == obj)

View File

@ -0,0 +1,11 @@
package com.example.demo.tages.repository;
import java.util.Optional;
import org.springframework.data.repository.CrudRepository;
import com.example.demo.tages.model.TageEntity;
public interface TageRepository extends CrudRepository<TageEntity, Long> {
Optional<TageEntity> findByNameIgnoreCase(String name);
}

View File

@ -0,0 +1,63 @@
package com.example.demo.tages.service;
import java.util.List;
import java.util.stream.StreamSupport;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.example.demo.core.error.NotFoundException;
import com.example.demo.tages.model.TageEntity;
import com.example.demo.tages.repository.TageRepository;
@Service
public class TageService {
private final TageRepository repository;
public TageService(TageRepository repository) {
this.repository = repository;
}
private void checkTage(String tage) {
if (repository.findByNameIgnoreCase(tage).isPresent()) {
throw new IllegalArgumentException(
String.format("Type with tage %s is already exists", tage));
}
}
@Transactional(readOnly = true)
public List<TageEntity> getAll() {
return StreamSupport.stream(repository.findAll().spliterator(), false).toList();
}
@Transactional(readOnly = true)
public TageEntity get(Long id) {
return repository.findById(id)
.orElseThrow(() -> new NotFoundException(TageEntity.class, id));
}
@Transactional
public TageEntity create(TageEntity entity) {
if (entity == null) {
throw new IllegalArgumentException("Entity is null");
}
checkTage(entity.getText());
return repository.save(entity);
}
@Transactional
public TageEntity update(Long id, TageEntity entity) {
final TageEntity existsEntity = get(id);
checkTage(entity.getText());
existsEntity.setText(entity.getText());
return repository.save(existsEntity);
}
@Transactional
public TageEntity delete(Long id) {
final TageEntity existsEntity = get(id);
repository.delete(existsEntity);
return existsEntity;
}
}

View File

@ -1,20 +1,37 @@
package com.example.demo.users.model; package com.example.demo.users.model;
import java.text.SimpleDateFormat;
import java.util.Date; import java.util.Date;
import java.util.HashSet;
import java.util.Objects; import java.util.Objects;
import java.util.Set;
import com.example.demo.comments.model.CommentEntity;
import com.example.demo.core.model.BaseEntity; import com.example.demo.core.model.BaseEntity;
import jakarta.persistence.CascadeType;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.OneToMany;
import jakarta.persistence.OrderBy;
import jakarta.persistence.Table;
@Entity
@Table(name = "users")
public class UserEntity extends BaseEntity { public class UserEntity extends BaseEntity {
@Column(nullable = false, unique = true, length = 20)
private String login; private String login;
@Column(nullable = false, unique = false, length = 20)
private String password; private String password;
@Column(nullable = false, unique = false, length = 150)
private String name; private String name;
@Column(nullable = false, unique = false, length = 50)
private String email; private String email;
private Date birthDate; private Date birthDate;
@OneToMany(mappedBy = "user", cascade = CascadeType.ALL)
@OrderBy("id ASC")
private Set<CommentEntity> comments = new HashSet<>();
public UserEntity() { public UserEntity() {
super();
} }
public UserEntity(Long id, String login, String password, String name, String email, Date birthDate) { public UserEntity(Long id, String login, String password, String name, String email, Date birthDate) {
@ -23,7 +40,6 @@ public class UserEntity extends BaseEntity {
this.password = password; this.password = password;
this.name = name; this.name = name;
this.email = email; this.email = email;
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
this.birthDate = birthDate; this.birthDate = birthDate;
} }
@ -67,6 +83,17 @@ public class UserEntity extends BaseEntity {
this.birthDate = birthDate; this.birthDate = birthDate;
} }
public Set<CommentEntity> getComments() {
return comments;
}
public void addComment(CommentEntity comment) {
if (comment.getUser() != this) {
comment.setUser(this);
}
comments.add(comment);
}
@Override @Override
public int hashCode() { public int hashCode() {
return Objects.hash(id, login, password, name, email, birthDate); return Objects.hash(id, login, password, name, email, birthDate);

View File

@ -1,10 +1,11 @@
package com.example.demo.users.repository; package com.example.demo.users.repository;
import org.springframework.stereotype.Repository; import java.util.Optional;
import org.springframework.data.repository.CrudRepository;
import com.example.demo.core.repository.MapRepository;
import com.example.demo.users.model.UserEntity; import com.example.demo.users.model.UserEntity;
@Repository public interface UserRepository extends CrudRepository<UserEntity, Long> {
public class UserRepository extends MapRepository<UserEntity> { Optional<UserEntity> findByLoginIgnoreCase(String login);
} }

View File

@ -1,9 +1,10 @@
package com.example.demo.users.service; package com.example.demo.users.service;
import java.util.List; import java.util.List;
import java.util.Optional; import java.util.stream.StreamSupport;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.example.demo.core.error.NotFoundException; import com.example.demo.core.error.NotFoundException;
import com.example.demo.users.model.UserEntity; import com.example.demo.users.model.UserEntity;
@ -17,31 +18,49 @@ public class UserService {
this.repository = repository; this.repository = repository;
} }
private void checkLogin(String login) {
if (repository.findByLoginIgnoreCase(login).isPresent()) {
throw new IllegalArgumentException(
String.format("Type with login %s is already exists", login));
}
}
@Transactional(readOnly = true)
public List<UserEntity> getAll() { public List<UserEntity> getAll() {
return repository.getAll(); return StreamSupport.stream(repository.findAll().spliterator(), false).toList();
} }
@Transactional(readOnly = true)
public UserEntity get(Long id) { public UserEntity get(Long id) {
return Optional.ofNullable(repository.get(id)) return repository.findById(id)
.orElseThrow(() -> new NotFoundException(id)); .orElseThrow(() -> new NotFoundException(UserEntity.class, id));
} }
@Transactional
public UserEntity create(UserEntity entity) { public UserEntity create(UserEntity entity) {
return repository.create(entity); if (entity == null) {
throw new IllegalArgumentException("Entity is null");
}
checkLogin(entity.getLogin());
return repository.save(entity);
} }
@Transactional
public UserEntity update(Long id, UserEntity entity) { public UserEntity update(Long id, UserEntity entity) {
final UserEntity existsEntity = get(id); final UserEntity existsEntity = get(id);
checkLogin(entity.getLogin());
existsEntity.setLogin(entity.getLogin()); existsEntity.setLogin(entity.getLogin());
existsEntity.setPassword(entity.getPassword()); existsEntity.setPassword(entity.getPassword());
existsEntity.setName(entity.getName()); existsEntity.setName(entity.getName());
existsEntity.setEmail(entity.getEmail()); existsEntity.setEmail(entity.getEmail());
existsEntity.setBirthDate(entity.getBirthDate()); existsEntity.setBirthDate(entity.getBirthDate());
return repository.update(existsEntity); return repository.save(existsEntity);
} }
@Transactional
public UserEntity delete(Long id) { public UserEntity delete(Long id) {
final UserEntity existsEntity = get(id); final UserEntity existsEntity = get(id);
return repository.delete(existsEntity); repository.delete(existsEntity);
return existsEntity;
} }
} }

View File

@ -1,6 +1,5 @@
package com.example.demo; package com.example.demo;
import java.util.Arrays;
import java.util.Date; import java.util.Date;
import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Assertions;
@ -10,16 +9,16 @@ import org.junit.jupiter.api.TestMethodOrder;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest;
import com.example.demo.comment.model.CommentEntity; import com.example.demo.comments.model.CommentEntity;
import com.example.demo.comment.service.CommentService; import com.example.demo.comments.service.CommentService;
import com.example.demo.core.error.NotFoundException; import com.example.demo.core.error.NotFoundException;
import com.example.demo.news.model.NewEntity; import com.example.demo.news.model.NewEntity;
import com.example.demo.tage.model.TageEntity; import com.example.demo.tages.model.TageEntity;
import com.example.demo.users.model.UserEntity; import com.example.demo.users.model.UserEntity;
@SpringBootTest @SpringBootTest
@TestMethodOrder(OrderAnnotation.class) @TestMethodOrder(OrderAnnotation.class)
public class CommentServiceTest { class CommentServiceTest {
@Autowired @Autowired
private CommentService commentService; private CommentService commentService;
@ -34,8 +33,7 @@ public class CommentServiceTest {
//create //create
var tage1 = new TageEntity(null, "пасха"); var tage1 = new TageEntity(null, "пасха");
var new1 = new NewEntity(null, "Чемпионат ICPC", new Date(), Arrays.asList(tage1), var new1 = new NewEntity(null, "Чемпионат ICPC", new Date(), "Студенты выступят на Чемпионате мира по программированию в Северной Евразии.");
"Студенты выступят на Чемпионате мира по программированию в Северной Евразии.");
var user1 = new UserEntity(null, "beko", "111", "ddwwdd", "beko@mail.ru", new Date()); var user1 = new UserEntity(null, "beko", "111", "ddwwdd", "beko@mail.ru", new Date());

View File

@ -14,7 +14,7 @@ import org.springframework.boot.test.context.SpringBootTest;
import com.example.demo.core.error.NotFoundException; import com.example.demo.core.error.NotFoundException;
import com.example.demo.news.model.NewEntity; import com.example.demo.news.model.NewEntity;
import com.example.demo.news.service.NewService; import com.example.demo.news.service.NewService;
import com.example.demo.tage.model.TageEntity;; import com.example.demo.tages.model.TageEntity;;
@SpringBootTest @SpringBootTest
@TestMethodOrder(OrderAnnotation.class) @TestMethodOrder(OrderAnnotation.class)
@ -30,18 +30,18 @@ class NewsServiceTest {
@Test @Test
void Test() { void Test() {
// create // create
List<TageEntity> list1 = Arrays.asList var tage1 = new TageEntity(null, "праздник");
(new TageEntity(null, "праздник"), new TageEntity(null, "сессия")); var tage2 = new TageEntity(null, "сессия");
newsService.create(new NewEntity(null, "Название", new Date(), list1, "текст новости")); newsService.create(new NewEntity(null, "Название", new Date(), "текст новости"));
final NewEntity last = newsService.create final NewEntity last = newsService.create
(new NewEntity(null, "9 апреля", new Date(), null, "просто наступил апрель")); (new NewEntity(null, "9 апреля", new Date(), "просто наступил апрель"));
Assertions.assertEquals(2L, newsService.getAll().size()); Assertions.assertEquals(2L, newsService.getAll().size());
Assertions.assertEquals(last, newsService.get(2L)); Assertions.assertEquals(last, newsService.get(2L));
// update // update
final var newNew = newsService.update(2L, new NewEntity(2L, "9 мая", new Date(), list1, "уже май!!!!!!!!!")); final var newNew = newsService.update(2L, new NewEntity(2L, "9 мая", new Date(), "уже май!!!!!!!!!"));
Assertions.assertEquals(2L, newsService.getAll().size()); Assertions.assertEquals(2L, newsService.getAll().size());
Assertions.assertEquals(newNew, newsService.get(2L)); Assertions.assertEquals(newNew, newsService.get(2L));

View File

@ -8,13 +8,12 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest;
import com.example.demo.core.error.NotFoundException; import com.example.demo.core.error.NotFoundException;
import com.example.demo.tage.model.TageEntity; import com.example.demo.tages.model.TageEntity;
import com.example.demo.tage.service.TageService; import com.example.demo.tages.service.TageService;
import com.example.demo.users.model.UserEntity;
@SpringBootTest @SpringBootTest
@TestMethodOrder(OrderAnnotation.class) @TestMethodOrder(OrderAnnotation.class)
public class TageServiceTest { class TageServiceTest {
@Autowired @Autowired
private TageService tageService; private TageService tageService;