-
Notifications
You must be signed in to change notification settings - Fork 152
[4기 - 김민희, 박세영] JPA 미션 1, 2, 3 PR 제출합니다. #321
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: 민희,세영-mission
Are you sure you want to change the base?
Conversation
@@ -0,0 +1,15 @@ | |||
classDiagram |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
good
int age, | ||
|
||
@NotBlank | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
해당 이메일 validation과 우리 요구사항에서의 validation이 다를 수 있습니다.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
패턴은 강의에서 사용해봤기 때문에 이메일 validation을 써보고 싶었습니다.
메시지를 지정해주는 방식으로 사용을 명확히 했습니다.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
validation message가 없네융
@Size(max = 3) | ||
int age, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@min 으로 제한을 걸어도 좋을거 같은데요?
name : !@#~~!@#박세영!@#!@#
age : -999살
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
이름에는 정규식,
나이에는 @ Min, @ Max 로 걸어두었습니다.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@devYSK min 유저한테 태그걸었심ㅋㅋ
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@WooSungHwan
ㅋㅋ ㅋㅋㅋㅋ ㅠㅠ
|
||
public record CustomerUpdateRequest( | ||
@NotBlank | ||
@Size(max = 50) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
메시지도 같이 넘겨주는것은 어떨까요?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
수정했습니다.
|
||
private void validateCustomer(Name name, Age age, Email email) { | ||
Assert.notNull(name, "name이 존재하지 않습니다."); | ||
Assert.notNull(age, "age가 존재하지 않습니다."); | ||
Assert.notNull(email, "email이 존재하지 않습니다."); | ||
} | ||
|
||
public void changeCustomer(CustomerDto customerDto) { | ||
changeName(customerDto.name()); | ||
changeAge(customerDto.age()); | ||
changeEmail(customerDto.email()); | ||
} | ||
|
||
private void changeName(Name name) { | ||
this.name = name; | ||
} | ||
|
||
private void changeAge(Age age) { | ||
this.age = age; | ||
} | ||
|
||
private void changeEmail(Email email) { | ||
this.email = email; | ||
} | ||
|
||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
private 중간에 public 메소드가 있어 눈에 잘 들어오지 않는다는 단점이 있어요.
규칙을 세우면 어떨까요?
|
||
@ActiveProfiles("test") | ||
@DataJpaTest | ||
@TestPropertySource(locations = "classpath:application-test.yaml") | ||
@AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
이 어노테이션들. 하나로 묶어서 custom 어노테이션을 사용해도 좋겠네요
@TestPropertySource(locations = "classpath:application-test.yaml") | ||
@AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE) | ||
class ItemRepositoryTest { | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
여긴 왜 given-when-then 패턴이 안보일까요!
다른 테스트코드와 통일성을 맞춰주세요
|
||
private static final Item item = Item.builder() | ||
.price(new Price(1000)) | ||
.nation(new OriginNation("KR")) | ||
.build(); | ||
|
||
private static final Item newItem = Item.builder() | ||
.price(new Price(2000)) | ||
.nation(new OriginNation("JP")) | ||
.build(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
외부에 Test Fixture 클래스를 만들어서 제공해줘도 좋을것같습니다
|
||
Item result = repository.findById(savedItem.getId()).get(); | ||
|
||
assertThat(result.getNation()).isEqualTo(item.getNation()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
레포지토리 레벨에선 id가 존재하는지 여부도 중요할것같네요
identity 전략이니까요
show_sql: true | ||
format_sql: true | ||
dialect: org.hibernate.dialect.MySQLDialect | ||
open-in-view: false |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
open-in-view false가 무엇을 의미할까요?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OSIV전략은 API 응답이 끝날 때까지 영속성 컨텍스트와 데이터베이스 커넥션을 유지하게 해줍니다!
영속성 컨텍스트의 범위가 뷰 단까지 이어져 지연로딩 등의 기능을 이용할 수 있지만, 현재 프로젝트에서는 Controller에 DTO를 넘겨주고 있기에 false로 설정 후 사용하고 있습니다!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
잘 아시는것 같습니다! 그러면 false로 의도한 이유가 더 궁금해 지네요.
true, false일때는 각각 어떤 trade-off가 있으며 어떤때에 어떻게 사용하는것이 좋을까요?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OSIV를 true로 켜놓는 경우, controller단에서 지연로딩을 사용할 수 있습니다.
다만, OSIV를 true로 켜놓는 경우 Controller 내에서 service로직을 수행할 때 영속성 컨텍스트 내에 있는 값을 변경한 후 @ Transactional이 걸린 로직을 바로 실행하는 경우 변경감지가 동작하여 값이 변경되는 것을 주의해야하며, DB 커넥션을 반환할 때 까지 물고있기때문에 동시 요청이 많은 실시간 트래픽이 중요한 시스템인 경우 장애가 발생할 수 있습니다!
OSIV를 false로 설정하는 경우에는 Controller(뷰 단)에서 지연로딩을 사용할 수 없습니다.
다만, DB 커넥션을 반환하는 시점이 트랜잭션이 끝나는 시점과 동일하여 위에서 언급한 OSIV가 true일 때 발생하는 문제점을 해결할 수 있습니다.
OSIV를 사용하기에 적합한 프로젝트는 서버 사이드 렌더링으로 구성되는 view단을 개발해야하는 경우라고 생각합니다.
현재 프로젝트는 API 기반의 프로젝트이고 Service에서 Controller로 dto를 넘겨주고 있기 때문에 OSIV를 false로 설정하여 개발했습니다!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
과제하시느라 수고 많으셨습니다 ㅎㅎ VO로 따로 빼서 embeddable을 고려하였다면 반드시 강한 비즈니스적 이유가 있어야하고 그 이유가 VO 안에 고스란히 들어있어야 할겁니다. 그 부분은 꼭 기억하셨으면 좋겠습니다. 단순히 랩핑한다고하고 이유를 들고 끝날 케이스가 아닙니다. 이 부분만 좀 짚고 넘어가시면 나중에 vo로 뺄지 심플하고 컴팩트하게 갈지 결정하기 쉬울 것 같습니다.
수고 많으셨습니다.
int age, | ||
|
||
@NotBlank | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
validation message가 없네융
@Size(max = 3) | ||
int age, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@devYSK min 유저한테 태그걸었심ㅋㅋ
Assert.notNull(name, "name이 존재하지 않습니다."); | ||
Assert.notNull(age, "age가 존재하지 않습니다."); | ||
Assert.notNull(email, "email이 존재하지 않습니다."); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
좋네여 ㅎㅎ
private void changeName(Name name) { | ||
this.name = name; | ||
} | ||
|
||
private void changeAge(Age age) { | ||
this.age = age; | ||
} | ||
|
||
private void changeEmail(Email email) { | ||
this.email = email; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
여기서도 Assert.nonNull 필요하지 않을까요?
//then | ||
Customer customer = customerRepository.findById(response.id()).get(); | ||
assertThat(response.id()).isEqualTo(customer.getId()); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@devYSK ㅋㅋㅋ 어디서 많이 들은 얘긴데 ㅋㅋㅋ 좋네요
assertThat(updatedCustomer.getName().getNameValue()).isEqualTo(request.name()); | ||
assertThat(updatedCustomer.getAge().getAgeValue()).isEqualTo(request.age()); | ||
assertThat(updatedCustomer.getEmail().getEmailAddress()).isEqualTo(request.email()); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Name, Age, Email 얘네들이 Entity 클래스 외부에서 사용 되어져야할 껀덕지가 있는가? 에 대한 부분도!
엔티티 내부 편의성을 위해 고려된게 아니라면 사실 분리도 그저 분리했다고밖에 이야기 할 수 밖에 없는 이유가 되겠죠. 대표적으로 예를 들자면 age 같은 녀석을 좀더 고립시키고 강한 비즈니스 요구사항이 필요로 해서 뺐다. 그럼 그 강한 요구사항이 저 Age 안에 들어있어야 해요. 근데 지금은 그런게 전혀 보이지 않아요... 그저 raw 데이터를 wrapping 한것 뿐이에요. 그렇게 했다고 객체지향의 근거로 작동할 순 없으니 뭔가 내가 개발하는게 삐끗한게 보였다면 그 원인부터 제거해야하는게 맞을 수도 있어보여요.
springboot-jpa
📌 과제 설명
👩💻 요구 사항과 구현 내용
✅ 피드백 반영사항
✅ PR 포인트 & 궁금한 점