From 552c5dcc937fcf37ab42668cf5d8711a39f0d24f Mon Sep 17 00:00:00 2001 From: jinho jeong Date: Fri, 22 Apr 2022 11:19:07 +0900 Subject: [PATCH] command entity --- README.md | 2 +- build.gradle | 4 ++- .../java/com/example/oneul/DTO/LoginDTO.java | 20 +++++++++++ .../exception/UserAlreadyExistException.java | 7 ++++ .../oneul/handler/GlobalExceptionHandler.java | 25 ++++++++++++++ .../java/com/example/oneul/model/Post.java | 18 ++++++++++ .../com/example/oneul/model/UserEntity.java | 27 +++++++++++++++ .../repository/UserCommandRepository.java | 6 ++-- .../service/command/UserCommandService.java | 10 ++++++ .../command/UserCommandServiceImpl.java | 34 +++++++++++++++++++ src/main/resources/application.yml | 8 +++-- .../oneul/service/UserCommandServiceTest.java | 26 ++++++++++++++ 12 files changed, 181 insertions(+), 6 deletions(-) create mode 100644 src/main/java/com/example/oneul/DTO/LoginDTO.java create mode 100644 src/main/java/com/example/oneul/exception/UserAlreadyExistException.java create mode 100644 src/main/java/com/example/oneul/handler/GlobalExceptionHandler.java create mode 100644 src/main/java/com/example/oneul/service/command/UserCommandService.java create mode 100644 src/main/java/com/example/oneul/service/command/UserCommandServiceImpl.java create mode 100644 src/test/java/com/example/oneul/service/UserCommandServiceTest.java diff --git a/README.md b/README.md index 2f7cad3..7f177fd 100644 --- a/README.md +++ b/README.md @@ -19,6 +19,6 @@ gradle bootJar java -jar build/libs/oneul-0.0.1-SNAPSHOT.jar ``` -## Next Step +## Next Level ### CQRS with separated persistance mechanisms

\ No newline at end of file diff --git a/build.gradle b/build.gradle index e605637..be09bad 100644 --- a/build.gradle +++ b/build.gradle @@ -23,11 +23,13 @@ repositories { dependencies { implementation 'org.springframework.boot:spring-boot-starter-web' implementation 'org.springframework.boot:spring-boot-starter-data-jpa' - implementation 'com.h2database:h2' + + runtimeOnly 'com.h2database:h2' compileOnly 'org.projectlombok:lombok' developmentOnly 'org.springframework.boot:spring-boot-devtools' annotationProcessor 'org.projectlombok:lombok' + testImplementation "org.testcontainers:junit-jupiter:1.16.3" testImplementation 'org.springframework.boot:spring-boot-starter-test' } diff --git a/src/main/java/com/example/oneul/DTO/LoginDTO.java b/src/main/java/com/example/oneul/DTO/LoginDTO.java new file mode 100644 index 0000000..af0f140 --- /dev/null +++ b/src/main/java/com/example/oneul/DTO/LoginDTO.java @@ -0,0 +1,20 @@ +package com.example.oneul.DTO; + +import com.example.oneul.model.UserEntity; + +public class LoginDTO { + private String username; + private String password; + + public LoginDTO(String username, String password){ + this.username = username; + this.password = password; + } + + public UserEntity toEntity(){ + return UserEntity.builder() + .username(username) + .password(password) + .build(); + } +} diff --git a/src/main/java/com/example/oneul/exception/UserAlreadyExistException.java b/src/main/java/com/example/oneul/exception/UserAlreadyExistException.java new file mode 100644 index 0000000..ee89a54 --- /dev/null +++ b/src/main/java/com/example/oneul/exception/UserAlreadyExistException.java @@ -0,0 +1,7 @@ +package com.example.oneul.exception; + +public class UserAlreadyExistException extends RuntimeException { + public UserAlreadyExistException(String message){ + super(message); + } +} diff --git a/src/main/java/com/example/oneul/handler/GlobalExceptionHandler.java b/src/main/java/com/example/oneul/handler/GlobalExceptionHandler.java new file mode 100644 index 0000000..99b6a86 --- /dev/null +++ b/src/main/java/com/example/oneul/handler/GlobalExceptionHandler.java @@ -0,0 +1,25 @@ +package com.example.oneul.handler; + +import com.example.oneul.exception.UserAlreadyExistException; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.web.bind.annotation.ControllerAdvice; +import org.springframework.web.bind.annotation.ExceptionHandler; + +@ControllerAdvice +public class GlobalExceptionHandler { + private static final Logger log = LoggerFactory.getLogger(GlobalExceptionHandler.class); + + @ExceptionHandler(Exception.class) + protected String handleException(Exception e){ + log.debug(e.getMessage()); + return e.toString(); + } + + @ExceptionHandler(UserAlreadyExistException.class) + protected String handleUserAlreadyExistException(UserAlreadyExistException e){ + log.debug(e.getMessage()); + return e.toString(); + } +} diff --git a/src/main/java/com/example/oneul/model/Post.java b/src/main/java/com/example/oneul/model/Post.java index 8925dd1..cd85780 100644 --- a/src/main/java/com/example/oneul/model/Post.java +++ b/src/main/java/com/example/oneul/model/Post.java @@ -25,6 +25,8 @@ public class Post { @ManyToOne(fetch = FetchType.LAZY, optional = false) private UserEntity writer; + public Post() {} + public Post(Long id, LocalDateTime createdAt, String content, UserEntity writer){ this.id = id; this.createdAt = createdAt; @@ -36,18 +38,34 @@ public class Post { return this.id; } + public void setId(Long id){ + this.id = id; + } + public LocalDateTime getCreatedAt(){ return this.createdAt; } + public void setCreatedAt(LocalDateTime createdAt){ + this.createdAt = createdAt; + } + public String getContent(){ return this.content; } + public void setConent(String content){ + this.content = content; + } + public UserEntity getWriter(){ return this.writer; } + public void setWriter(UserEntity writer){ + this.writer = writer; + } + @Override public String toString(){ return "Post[" diff --git a/src/main/java/com/example/oneul/model/UserEntity.java b/src/main/java/com/example/oneul/model/UserEntity.java index 4340e7b..7fdf5e9 100644 --- a/src/main/java/com/example/oneul/model/UserEntity.java +++ b/src/main/java/com/example/oneul/model/UserEntity.java @@ -29,18 +29,34 @@ public class UserEntity { return this.id; } + public void setId(Long id){ + this.id = id; + } + public String getUsername(){ return this.username; } + public void setUsername(String username){ + this.username = username; + } + public String getPassword(){ return this.password; } + public void setPassword(String password){ + this.password = password; + } + public LocalDateTime getCreatedAt(){ return this.createdAt; } + public void setCreatedAt(LocalDateTime createdAt){ + this.createdAt = createdAt; + } + public UserEntity(Long id, String username, String password, LocalDateTime createdAt){ this.id = id; this.username = username; @@ -48,6 +64,13 @@ public class UserEntity { this.createdAt = createdAt; } + public UserEntity(UserEntity user){ + this.id = user.getId(); + this.username = user.getUsername(); + this.password = user.getPassword(); + this.createdAt = user.getCreatedAt(); + } + @Override public String toString(){ return "userEntity[" @@ -56,6 +79,10 @@ public class UserEntity { + ", createdAt: " + this.createdAt + "]"; } + public static Builder builder() { + return new Builder(); + } + public static class Builder { private Long id; private String username; diff --git a/src/main/java/com/example/oneul/repository/UserCommandRepository.java b/src/main/java/com/example/oneul/repository/UserCommandRepository.java index ec5b7d5..43590f3 100644 --- a/src/main/java/com/example/oneul/repository/UserCommandRepository.java +++ b/src/main/java/com/example/oneul/repository/UserCommandRepository.java @@ -1,5 +1,7 @@ package com.example.oneul.repository; +import java.util.Optional; + import com.example.oneul.model.UserEntity; import org.springframework.data.repository.CrudRepository; @@ -7,5 +9,5 @@ import org.springframework.stereotype.Repository; @Repository public interface UserCommandRepository extends CrudRepository { - -} + Optional findByUsername(String username); +} \ No newline at end of file diff --git a/src/main/java/com/example/oneul/service/command/UserCommandService.java b/src/main/java/com/example/oneul/service/command/UserCommandService.java new file mode 100644 index 0000000..fe17782 --- /dev/null +++ b/src/main/java/com/example/oneul/service/command/UserCommandService.java @@ -0,0 +1,10 @@ +package com.example.oneul.service.command; + +import com.example.oneul.model.UserEntity; + +import org.springframework.stereotype.Service; + +@Service +public interface UserCommandService { + UserEntity signUp(UserEntity userEntity); +} diff --git a/src/main/java/com/example/oneul/service/command/UserCommandServiceImpl.java b/src/main/java/com/example/oneul/service/command/UserCommandServiceImpl.java new file mode 100644 index 0000000..ff83541 --- /dev/null +++ b/src/main/java/com/example/oneul/service/command/UserCommandServiceImpl.java @@ -0,0 +1,34 @@ +package com.example.oneul.service.command; + +import com.example.oneul.exception.UserAlreadyExistException; +import com.example.oneul.model.UserEntity; +import com.example.oneul.repository.UserCommandRepository; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Isolation; +import org.springframework.transaction.annotation.Transactional; + +@Service +@Transactional +public class UserCommandServiceImpl implements UserCommandService { + private final UserCommandRepository userCommandRepository; + private final Logger log = LoggerFactory.getLogger(UserCommandServiceImpl.class); + + public UserCommandServiceImpl(UserCommandRepository userCommandRepository){ + this.userCommandRepository = userCommandRepository; + } + + @Override + @Transactional(isolation = Isolation.SERIALIZABLE) + public UserEntity signUp(UserEntity userEntity){ + userCommandRepository.findByUsername(userEntity.getUsername()).ifPresent(user -> { + log.debug(user.getUsername() + " is present"); + throw new UserAlreadyExistException(userEntity.getUsername() + " is already exist."); + }); + UserEntity user = new UserEntity(userEntity); + return userCommandRepository.save(user); + } +} + diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index 0e492c6..719ca36 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -1,6 +1,5 @@ spring: jpa: - database: "h2" properties: hibernate: show-sql: true @@ -8,10 +7,15 @@ spring: hbm2ddl: auto: update format_sql: true + datasource: + url: jdbc:h2:tcp://localhost/~/test + driver-class-name: org.h2.Driver + username: "sa" logging: level: web: DEBUG org: hibernate: - SQL: DEBUG \ No newline at end of file + SQL: DEBUG + diff --git a/src/test/java/com/example/oneul/service/UserCommandServiceTest.java b/src/test/java/com/example/oneul/service/UserCommandServiceTest.java new file mode 100644 index 0000000..ed983c1 --- /dev/null +++ b/src/test/java/com/example/oneul/service/UserCommandServiceTest.java @@ -0,0 +1,26 @@ +package com.example.oneul.service; + +import com.example.oneul.DTO.LoginDTO; +import com.example.oneul.model.UserEntity; +import com.example.oneul.service.command.UserCommandService; + +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.junit.jupiter.MockitoExtension; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.transaction.annotation.Transactional; + +@Transactional +@SpringBootTest +@ExtendWith(MockitoExtension.class) +public class UserCommandServiceTest { + @Autowired + private UserCommandService userCommandService; + + @Test + public void signUpTest(){ + LoginDTO loginDTO = new LoginDTO("zzzinho", "password"); + UserEntity user = userCommandService.signUp(loginDTO.toEntity()); + } +}