안녕하세요 영한님, 정말 좋은강의 잘 듣고있습니다. Merge관련해서 질문이 하나있는데요..! 아래 두 method 모두 시작할때 persistence context가 비어있고 찾는 entity가 db에 있다고 가정할때 비슷한 (혹은 같은) flow로 진행될까요? 여기서 method parameter, Entity e,는 업데이트될 (id가 set되어있고 field가 업데이트 되어있는)객체입니다. @Transactional public void updateEntity(Entity e){ Entity foundEntity = em.find(Entity.class, e.getid()); foundEntity.setFieldOne("New Data"); } @Transactional public void updateEntity(Entity e){ em.merge(e); } Merge를 꼭 써야하는건 아니지만, 그냥 동작 메커니즘이 궁금해서 질문드립니다. Merge를 쓰는게 Update전에 항상 Select query로 db에서 객체를 조회하기때문에 쓰기를 지양하라고 하시는건가요, 아니면 merge를 쓸때 또 다른 downside가 있나요?
따라하며 배우는 노드, 리액트 시리즈 - 레딧 사이트 만들기(NextJS)(Pages Router)
docker-compose up을 사용하면 initdb: error: directory "/var/lib/postgresql/data" exists but is not empty initdb: hint: If you want to create a new database system, either remove or empty the directory "/var/lib/postgresql/data" or run initdb with an argument other than "/var/lib/postgresql/data". 라는 오류가 자꾸 발생합니다. 삭제하고 다시 해도 해결이 안되서 질문남깁니다. 어떻게 해결해야하나요.
섹션 4. 회원 도메인 개발-회원서비스 개발에 대해 질문있습니다. 테스트 junit으로 테스트 실행시 아래와 같은 에러가 나옵니다. Execution failed for task ':test'. > No tests found for given includes: [jpabook.jpashop.Service.MemberServiceTest](filter.includeTestsMatching) package jpabook.jpashop.Service; import static org.junit.Assert.*; import jpabook.jpashop.domains.Member; import jpabook.jpashop.repository.MemberRepository; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.junit4.SpringRunner; import org.springframework.transaction.annotation.Transactional; //메모리db로 test import static org.junit.jupiter.api.Assertions.*; import static org.junit.jupiter.api.Assertions.assertEquals; @RunWith(SpringRunner.class) @SpringBootTest @Transactional class MemberServiceTest { @Autowired MemberService memberService; @Autowired MemberRepository memberRepository; @Test public void 회원가입() throws Exception { //given Member member = new Member(); member.setName("kim"); //when Long savedId = memberService.join(member); //then assertEquals(member, memberRepository.findOne(savedId)); } // @Test // public void 중복회원예외() throws Exception { // //given // // //when // // //then // // } } 에러 사항을 찾아보니 디렉토리 위치가 다를 경우에 에러가 날 수 있다고 하여 디렉토리 위치를 비교해봐도 같습니다. junit테스트도 동일합니다. 어느 부분이 틀린지 알 수 있을까요?
[질문 템플릿] 1. 강의 내용과 관련된 질문인가요? (예 2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예 3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예 [질문 내용] 스프링 cascade 활용도 측면에서 궁금한 것이 있습니다. 영한님 - 인프런 (inflearn.com) 이 질문을 남겼었던 수강생입니다! 잠깐 상황을 요약하면 Program 과 Review 그리고 User 가 다대 1 1대 다 로 묶여 있는 상황입니다. program 에서 program.addReview 메서드를 활용하기 위해 cascade type 을 적용하였었습니다. 하지만 영한 님은 이부분의 코드는 별로 좋은 코드가 아니다! cascade 옵션 질문 - 인프런 (inflearn.com) 를 참고해서 보아라. 라고 하셨습니다. 위 질문의 요약은 강의에서 Order 는 OrderItem 을 개인 소유 하나, Order 와 Delivery 는 Delivery 가 여러 곳에서 참조할 수 있으므로 개인 소유 하지 않는다. 라고 읽었습니다. 참조 하는 것과 Cascade Type .all 이 무슨 관계가 있는지 모르겠습니다. 6줄요약하면: Delivery 와 Review 는 여러 곳에서 참조할 수 있으므로 CascadeType all 을 붙이지 말라고 하신 것 같은데 여러 곳에서 참조가능성이 있으면 CascadeType all 을 왜 붙이지 말아야 하는지 궁금합니다. 단순히 계속 코드를 보며 추적해야 하는 것 때문인가요?? 이 부분이 와닿지 않습니다. 혹시 실제 예를 들어 설명해주실수 있나요??
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요. 1. 강의 내용과 관련된 질문을 남겨주세요. 2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요. (자주 하는 질문 링크: https://bit.ly/3fX6ygx) 3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요. (질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG) 질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요. ========================================= [질문 템플릿] 1. 강의 내용과 관련된 질문인가요? (예) 2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예) 3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예) [질문 내용] 여기에 질문 내용을 남겨주세요. 이게 현재 프로젝트 이고 plugins { id 'java' id 'org.springframework.boot' version '3.2.3' id 'io.spring.dependency-management' version '1.1.4' id 'com.ewerk.gradle.plugins.querydsl' version '1.0.10' } group = 'study' version = '0.0.1-SNAPSHOT' java { sourceCompatibility = '17' } configurations { compileOnly { extendsFrom annotationProcessor } } repositories { mavenCentral() } dependencies { implementation 'org.springframework.boot:spring-boot-starter-data-jpa' implementation 'org.springframework.boot:spring-boot-starter-web' compileOnly 'org.projectlombok:lombok' developmentOnly 'org.springframework.boot:spring-boot-devtools' runtimeOnly 'com.mysql:mysql-connector-j' annotationProcessor 'org.projectlombok:lombok' testImplementation 'org.springframework.boot:spring-boot-starter-test' implementation 'com.github.gavlyukovskiy:p6spy-spring-boot-starter:1.9.0' //test 롬복 사용 testCompileOnly 'org.projectlombok:lombok' testAnnotationProcessor 'org.projectlombok:lombok' //Querydsl 추가 implementation 'com.querydsl:querydsl-jpa:5.1.0:jakarta' annotationProcessor "com.querydsl:querydsl-apt:5.1.0:jakarta" annotationProcessor "jakarta.annotation:jakarta.annotation-api" annotationProcessor "jakarta.persistence:jakarta.persistence-api" } tasks.named('test') { useJUnitPlatform() } clean { delete file('src/main/generated') } //querydsl 추가 시작 def querydslDir = file('build/generated/querydsl') querydsl { jpa = true querydslSourcesDir = querydslDir } sourceSets { main.java.srcDir querydslDir } configurations { querydsl.extendsFrom compileClasspath } compileQuerydsl { options.annotationProcessorPath = configurations.querydsl } 현재 gradle설정인데 Querydsl 설정과 검증 부분에서 막혔어요 클린해서 q파일 지우고 테스트 코드 런하면 아래 에러가 나타나고 error: Attempt to recreate a file for type study.querydsl.entity.QHello 이후에 q파일이 생성 된 후에는 error: Could not find class file for 'study.querydsl.entity.Hello'. 에러가 반복되네요.. https://www.inflearn.com/questions/1086099 다른분들 설정파일 따라해도 안됩니다..
public class Animal { public void sound(){ System.out.println("동물 울음 소리"); } } public class Dog extends Animal{ @Override public void sound() { System.out.println("멍멍"); } } public class BabyDog extends Dog{ public void sound() { System.out.println("낑낑"); } } public class AnimalPolyMain1 { public static void main(String[] args) { Dog dog = new Dog(); BabyDog babyDog = new BabyDog(); soundAnimal(dog); soundAnimal(babyDog); } private static void soundAnimal(Animal animal){ System.out.println("동물 소리 테스트 시작"); animal.sound(); System.out.println("동물 소리 테스트 종료"); } } 안녕하세요. 강의 중 추가적으로 궁금한게 생겨서 질문드립니다. 그림에 따르면 코드에 만약에 제가 BabyDog클래스를 만들어서 Dog를 extends 한 후 오버라이딩을 하지 않고 매서드를 생성하면 "낑낑"이 아닌 매서드 오버라이딩이 된 "멍멍"이 출력되어야 하는 거 아닌가요??
[질문 템플릿] 1. 강의 내용과 관련된 질문인가요? (예/아니오) 예 2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오) 있긴한데 좀 다릅니다 3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오) 예 [질문 내용] 연관관계 편의메서드와 관련된 질문입니다. public void setMember(Member member) { this.member = member; member.getOrders().add(this); } public void addOrderItem(OrderItem orderItem) { orderItems.add(orderItem); orderItem.setOrder(this); } public void setDelivery(Delivery delivery) { this.delivery = delivery; delivery.setOrder(this); } 공부하던 도중 일대다, 다대일, 일대일 연관관계 매서드가 모두 다른 것을 발견했습니다. 제 궁금증은 다대일에서는 왜 meber.getOrders().add(this)로 세팅하고 일대일이나 다대일에서는 orderItem.setOrder(this)로 세팅하는지 궁금한 것 입니다. 커뮤니티에 관련 질문을 찾던 도중 jpa 기본편을 보시라고 하셨는데 위치를 못 찾겠습니다. 알려주시면 감사하겠습니다. 추가로 제가 자바의 List의 메소드에 대한 이해가 부족해서 모르는가 싶기도 한데 그게 맞을까요?
sudo kubeadm init 명령어를 입력했는데 다음과 같은 에러가 발생합니다. ttasjwi20240228@master-1:~$ sudo kubeadm init [init] Using Kubernetes version: v1.29.2 [preflight] Running pre-flight checks error execution phase preflight: [preflight] Some fatal errors occurred: [ERROR CRI]: container runtime is not running: output: time="2024-03-04T06:52:20Z" level=fatal msg="validate service connection: validate CRI v1 runtime API for endpoint \"unix:///var/run/containerd/containerd.sock\": rpc error: code = Unimplemented desc = unknown service runtime.v1.RuntimeService" , error: exit status 1 [preflight] If you know what you are doing, you can make a check non-fatal with `--ignore-preflight-errors=...` To see the stack trace of this error execute with --v=5 or higher 이런 문제가 발생하네요. 검색해보면 2020년 containerd github에 이런 증상에 관한 이슈가 올라와져있습니다. https://github.com/containerd/containerd/issues/4581 이 이슈의 답변에는 이런 내용이 있습니다. c ontainerd.io 패키지에 의해 설치된 config.toml 파일에는 disabled_plugins = ["cri"]라는 줄이 있는데, 이것이 문제를 일으킨 것으로 보입니다. 이 문제를 해결하려면 다음 명령을 실행하시면 됩니다. sudo rm /etc/containerd/config.toml sudo systemctl restart containerd sudo kubeadm init 혹시 워커노드에서 join할 때도 동일한 문제 생기면 sudo rm /etc/containerd/config.toml sudo systemctl restart containerd 이 명령을 워커노드에 입력해봅시다
아래에 23년 당시 설치방법을 올리신 분의 것으로도 잘 안 되서... 그 사이에 또 바뀌었나 싶어서 노션 링크의 공식 문서를 보고 따라했습니다만 apt 명령으로 kubelet, kubeadm, kubectl이 설치가 안 되는 문제가 있습니다. 노션 링크의 공식문서는 한국어 문서였고, 최신화가 안 되어있던 것입니다. 영어 문서 를 봐야합니다. 현재 공식문서에서는 이런 말이 나와있습니다. Note: The legacy package repositories ( apt.kubernetes.io and yum.kubernetes.io ) have been deprecated and frozen starting from September 13, 2023 . Using the new package repositories hosted at pkgs.k8s.io is strongly recommended and required in order to install Kubernetes versions released after September 13, 2023. The deprecated legacy repositories, and their contents, might be removed at any time in the future and without a further notice period. The new package repositories provide downloads for Kubernetes versions starting with v1.24.0. apt.kubernetes.i and yum.kubernetes.io 레거시 패키지 리포지토리 deprecated apt.kubernetes.io and yum.kubernetes.io 2023년 8월 13일 이후 릴리즈되는 새로운 쿠버네티스 버전을 설치하기 위해서는 새로운 패키지 리포지토리를 써라 http://pkgs.k8s.io 새로운 패키지 리포지토리는 1.24.0 ~ 이후의 버전을 지원 이런 내용이 한국어 문서에는 반영이 안 됐습니다. 해당 문서에서는 1.29.0을 설치하기 위해 다음을 하라고 합니다. apt 패키지 인덱스를 업데이트하고 Kubernetes apt 저장소를 사용하는 데 필요한 패키지를 설치하십시오: sudo apt-get update sudo apt-get install -y apt-transport-https ca-certificates curl gpg Kubernetes 패키지 저장소의 공개 서명 키를 다운로드하십시오. 모든 저장소에 동일한 서명 키가 사용되므로 URL에서 버전을 무시할 수 있습니다: (우분투 20.04에서는 sudo mkdir -p -m 755 /etc/apt/keyrings 명령어를 입력해야합니다) # If the folder `/etc/apt/keyrings` does not exist, it should be created before the curl command, read the note below. # sudo mkdir -p -m 755 /etc/apt/keyrings curl -fsSL https://pkgs.k8s.io/core:/stable:/v1.29/deb/Release.key | sudo gpg --dearmor -o /etc/apt/keyrings/kubernetes-apt-keyring.gpg 적절한 Kubernetes apt 저장소를 추가하십시오. 이 저장소에는 Kubernetes 1.29에 대한 패키지만 있으므로, 다른 Kubernetes 마이너 버전을 사용하는 경우 URL에서 Kubernetes 마이너 버전을 원하는 버전에 맞게 변경해야 합니다(설치할 Kubernetes 버전의 문서를 읽고 있는지도 확인해야 합니다). # This overwrites any existing configuration in /etc/apt/sources.list.d/kubernetes.list echo 'deb [signed-by=/etc/apt/keyrings/kubernetes-apt-keyring.gpg] https://pkgs.k8s.io/core:/stable:/v1.29/deb/ /' | sudo tee /etc/apt/sources.list.d/kubernetes.list apt 패키지 인덱스를 업데이트하고 kubelet, kubeadm 및 kubectl을 설치하고 버전을 고정하십시오: sudo apt-get update sudo apt-get install -y kubelet kubeadm kubectl sudo apt-mark hold kubelet kubeadm kubectl 결론 바로 위 내용을 그대로 적용하신다면 아래 내용을 복사 붙여넣기 하시면 돼요. cat <<EOF > kube_install.sh # /etc/apt/keyrings 폴더 생성 및 권한 부여 sudo mkdir -p -m 755 /etc/apt/keyrings # 1. apt 패키지 색인을 업데이트하고, 쿠버네티스 apt 리포지터리를 사용하는 데 필요한 패키지를 설치한다. sudo apt-get update sudo apt-get install -y apt-transport-https ca-certificates curl gpg # 2. 구글 클라우드의 공개 사이닝 키를 다운로드 한다. sudo curl -fsSL https://pkgs.k8s.io/core:/stable:/v1.29/deb/Release.key | sudo gpg --dearmor -o /etc/apt/keyrings/kubernetes-apt-keyring.gpg # 3. 쿠버네티스 apt 리포지터리를 추가한다. echo 'deb [signed-by=/etc/apt/keyrings/kubernetes-apt-keyring.gpg] https://pkgs.k8s.io/core:/stable:/v1.29/deb/ /' | sudo tee /etc/apt/sources.list.d/kubernetes.list # 4. apt 패키지 색인을 업데이트하고, kubelet, kubeadm, kubectl을 설치하고 해당 버전을 고정한다. sudo apt-get update sudo apt-get install -y kubelet kubeadm kubectl sudo apt-mark hold kubelet kubeadm kubectl EOF sudo bash kube_install.sh kubeadm version 실행 후 버전 확인을 해보시면 됩니다 지금 자료는 2024.03.04 기준 공식문서(영어<- 중요) 자료고 내일 당장 바뀔 수도 있습니다. 제가 지금 올린 내용을 믿으시지 마시고 일단 먼저 공식문서 (영어 <- 중요) 를 참고하세요!
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요. 1. 강의 내용과 관련된 질문을 남겨주세요. 2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요. (자주 하는 질문 링크: https://bit.ly/3fX6ygx) 3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요. (질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG) 질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요. ========================================= [질문 템플릿] 1. 강의 내용과 관련된 질문인가요?예 2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? 예 3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오) [질문 내용] 강의 내용과 그대로 세타조인을 따라 했는데 query나온 것을 보니 cross join이 없어요 그리고 left join도 처음 sql에서는 left join이 나오는데 번역된 sql에서는 left join이 생략되는데 jpa가 최적화를 한 것일까요?
이 부분이 생성메서드 부분인데요.. 대부분 setter를 사용하여 서비스계층에서 해야 할 로직을 엔터티 내에서 처리하고 있는데 영한 선생님께서 강조하시는 setter를 열어두지 않는다면(필요에 따라서는 열어두라고 하셧는데...) 어떤식으로 처리하는지 도저히 감이 잡히지 않네요..ㅜ 이 부분 설명해주시는 강의 챕터가 따로 있을까요?
안녕하세요. OSIV 강의 후반부 내용에서 규모가 비교적 큰 프로젝트에서는 도메인 계층과 더불어 그 앞단에 애플리케이션 계층을 추가하는걸 고려해보라고 말씀주신 내용이 있었는데요. 이게 제가 찾고 있는 해답이 아닐까 싶어 조금 더 자세히 알고 싶어 질문 드립니다. 질문이 조금은 장황해도 너그러히 이해주시면 감사드리겠습니다. 최근에 개인 프로젝트를 수행해보면서 제가 학습해온 개념들(JPA, DDD, MSA)이 중점적으로 다루는 내용이 다르다보니 프로젝트 구성에서 혼란을 겪어오고 있습니다. 현재 개인 프로젝트 패키지 구조는 제가 느끼기에 가장 와닿았던 controller - application - domain - repository로 나뉘어 개발하고 있습니다. 이때 application 계층의 역할은 하나의 요구사항(가입, 해지 등)을 해결하기 위해 필요한 하위 계층의 애플리케이션 서비스들을 호출하는 facade를 구성합니다. 또, domain에서는 도메인 객체와 더불어 해당 도메인의 애플리케이션 서비스를 통해 비즈니스적 처리를 추상화하여 표현하고, 데이터 핵심 데이터 처리를 repository에 위임하도록 구성했습니다. 다만 이해가 안 갔던건 트랜잭션을 처리 계층에 대한 내용인데요. 제가 본 msa 도서에서는 facade에서 수행되는 애플리케이션 서비스 각각이 서로 다른 도메인 처리이므로 application 계층이 아닌, domain 메소드 단위로 트랜잭션이 구성되어야한다더라구요. 그런데 사실 제가 개발하고 있는 프로젝트는 MSA 구조가 아니고, 여러 에그리거트가 복합된 구조이기에 위 구조와 사상을 가지고 개발하기 어렵다는 생각이 들었습니다. 또한, 서로 다른 도메인의 애플리케이션 서비스간에 호출관계에서도 어려움을 겪었는데요. 예를 들어, 두 user가 하나의 group을 구성하는 서비스를 만들 때도 groupService라는 group에 종속된 애플리케이션 서비스에서 두 사용자 정보를 불러오는 userService 주입하자니, 서로 상이한 서비스간에 불필요한 의존성이 생기고, 같은 레벨의 서비스를 참조하는 것이 어색하다고 느껴졌습니다. 그래서 facade 계층에서 두 서비스를 주입하여 그룹생성 절차를 처리하자니 한 트랜잭션에 처리되어야한다고 생각하는 그룹 생성 처리 절차에서 회원, 그룹 서비스의 트랜잭션이 분리되니 이상하다고 생각했습니다. 드디어 본격적인 질문인데요. 혹시 영한님께서 말씀하신 애플리케이션 계층이 이렇게 도메인에 종속된 두 개 이상의 서비스가 함께 쓰여야 할 때 쓰이는 것이 맞을까요? 맞다면 controller - application - domain - repository 의 계층구조에서 facade가 들어가던 application에 해당 복합(?) 서비스를 구현하고, 해당 서비스에 대한 dto객체정도들만 구현하면 되는걸까요? 3. 굳이 어플리케이션 계층이 필요로 하지않은 하나의 도메인에만 종속된 기능들을 호출구조를 어떻게 가야할까요? 애플리케이션 계층을 도입한 상황에서 controller에서 domain 계층을 바로 호출하는 것은 일관성이 없어보이고, 또 일관성을 맞추기위해 application 계층에서 도메인 계층으로 BYPASS하는 객체를 만드는 것도 비효율적으로 보이긴합니다. 각각의 케이스에 어떻게 가는게 좋을까요?
9:57 보시면 51 라인 Account account = accountRepository.findByEmail(email); 이 순간 account 객체는 Persistent 상태이고, 이 코드 이후로 account 이건 다시 detach 상태가 되는데 63라인 accountService.completeSignUp(account); 이 코드로 인하여 다시 Persistent 로 상태가 만들어진다고 생각하면 될까요 ?? (왜냐하면 accountService.completeSignUp(account);에는 트랜잭션어노테이션이붙어있어서)
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요. 1. 강의 내용과 관련된 질문을 남겨주세요. 2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요. (자주 하는 질문 링크: https://bit.ly/3fX6ygx) 3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요. (질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG) 질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요. ========================================= [질문 템플릿] 1. 강의 내용과 관련된 질문인가요? (예/아니오) 2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오) 3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오) [질문 내용] 소스코드가 포함된 강의 자료 다운받으려하는데 어디에 있나요?
[질문 템플릿] 1. 강의 내용과 관련된 질문인가요? (예/아니오) 2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오) 3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오) [질문 내용] HelloSpringApplication 실행 시 아래와 같은 입력 상자가 뜨는데 이유가 뭔가요?
안녕하세요. 11:03 경에 "이런 것들 json으로 말아넣자"라고 말씀하신 부분이요. 조금 더 풀어서 설명해주실 수 있을까요? 당장 이 프로세스가 필요해서는 아니지만 개념적으로라도 알고 있으려고 합니다! "이런 데이터"에 관해서도 조금 더 풀어서 말씀해주실 수 있을까요? 어떤 성격의 데이터들은 테이블이 아니라 json으로 관리할 수 있다는 것인지 조금 더 구체적으로 알고 싶습니다. 감사합니다.