자바와 스프링 부트로 생애 최초 서버 만들기, 누구나 쉽게 개발부터 배포까지! [서버 개발 올인원 패키지]
안녕하세요 선생님. 강의를 듣던 중 궁금한 점이 생겨서 이렇게 글을 남기게되었습니다. UserLoanHistory라는 Entitiy는 강의에서 말씀하셨듯이 User와 ManyToOne의 관계를 가져가는데, 이게 또 Book과의 관계를 보더라도 ManyToOne이 성립할수 있지 않나 싶습니다.(물론 UserLoanHistory의 변수로 pk인 bookId가 아닌 bookName을 쓰셔서 조금 다를수 있지만...) 따라서 user_loan_history 테이블을 설계할때 칼럼을 book_name이 아닌 book_id로 해서 만든다면 그게 좋은 선택일지 궁금합니다 만일 1번의 테이블 설계가 나쁘지 않은 방식이라면 UserLoanHistory Entity에 Book에 대해서도 ManyToOne을 무조건 해주는게 좋은지, 아니면 '유저'의 대출기록만 자주 쓰이고 '책'의 대출기록은 거의 조회되지않을거 같으면 굳이 ManyToOne을 해줄 필요가 없을지 궁금합니다.
제미니님 안녕하세요. 강의를 통해 각 개념 간의 응집성을 높이고, 불필요한 의존성을 줄여 격벽을 세우는 설계를 깊이 있게 연습하고 있습니다. 강의에서 배운 원칙을 적용하여 '리뷰'나 '찜' 같은 개념들이 '상품' 개념을 단방향으로 참조하도록 구조를 잡고 있습니다. 하지만 실제 상품 목록 조회 기능을 구현하다 보니, 설계의 일관성을 유지하기 어려운 상황을 마주하게 되어 조언을 구하고자 합니다. 개념 간 의존성의 역전: 목록 화면에서 '리뷰 수'나 '찜 수'를 함께 보여주거나, 이를 기준으로 상품을 정렬해야 하는 요구사항이 생겼습니다. 이 경우 상품 개념이 본래 몰라야 할 하위 개념(리뷰, 찜 등)의 상태를 알아야만 하는 상황이 발생합니다. API 구성의 어려움: 상세 페이지는 API를 잘게 나누어 클라이언트에서 합성함으로써 개념 간의 독립성을 지킬 수 있지만, 목록의 경우 수십 개의 상품에 대해 매번 각각의 리뷰 수 API를 호출하여 클라이언트가 매핑하는 방식은 어딘가 어색하고 성능과 구현 효율 면에서 의문이 듭니다. 결국 조회를 위해 상품이 다시 리뷰나 찜을 알게 되면, 처음 설계한 개념 간의 단방향 참조 구조가 깨지거나 서로를 참조하는 순환 참조가 발생할 것 같아 우려됩니다. 이처럼 개념 간의 격벽을 유지하려는 설계 원칙과, 여러 개념의 데이터가 한꺼번에 필요한 조회 요구사항이 충돌할 때 어떤 식으로 접근하는 것이 현명할까요? 원칙을 고수하며 우회할 방법이 있을지, 혹은 이런 조회 상황에서는 설계적 타협이 필요한 것인지 견해를 듣고 싶습니다.
spring boot4 + 이클립스를 사용중입니다. src/test/resources 경로에 applicaion.yaml파일을 넣어도 인식을 못해서 3시간을 해맸습니다.. 구글링으로 java build path에서 설정 경로를 확인할 수 있다는 사실을 알게되었는데 src/test/java 경로로 설정이 되어있더군요. 여기 경로에 넣으니까 잘 작동됩니다. 어째서 src/test/resources 경로가 기본값이 아니였던걸까요..
명령어에서 startDateTime, endDateTime 의 jobParameters 부재 코드에서 @StepScope 어노테이션과 startDateTime, endDateTime 의 jobParameters 파라미터 부재 1번은 다른 사람이 심지어 이전에 쓴 문제더라고 ? 아마 형이 반영 안한건 모아서 한번에 수정할 계획인거 같아 보이네. 2번의 경우에는 @StepScope 도 빠져서 JobParameter 를 입력해도 오류가 발생했어. 또한 해당 메소드의 파라미터 부분을 1번과 마찬가지로 jobparameter로 받아야 할 것으로 보여져. 읽다가 하나씩 돌려보는데, 오류 터져서 놀라가지고 시간을 좀 썼어, 형. 1번은 내가 이해하는데, 2번은 형 실수가 좀 큰듯.
질문 가이드 읽고 삭제 후 오타제보 JobScope와 StepScope 사용 시 주의사항 ... 2. Step 빈에는 @StepScope와 @JobScope와를 사용하지 말라. -> @Step 빈에는 @StepScope 와 @JobScope 와 를 사용하지 말라 -> 말이 확실히 이상해
형 스프링부트 4에서는 jdbc starter 추가 안하면 안되던데 뭐지 ```build.gradle.kts description = "batch" dependencies { implementation("org.springframework.boot:spring-boot-starter-jdbc") implementation("org.springframework.boot:spring-boot-starter-batch") implementation("org.springframework.boot:spring-boot-h2console") runtimeOnly("com.h2database:h2") testImplementation("org.springframework.boot:spring-boot-starter-batch-test") } ``` implementation("org.springframework.boot:spring-boot-starter-jdbc") 위 처럼 의존성 명시적으로 처리해주기 전에는 아래 에러떳었어. Could not autowire. No beans of 'PlatformTransactionManager' type found.
누구보다 빠르게 배우는 Nginx + Docker + Springboot 서버 무중단 배포
강의에선 컨테이너 이미지를 DockerHub에 등록해서 사용하셨고, 리버스 프록시를 위해 EC2에 Nginx를 띄워서 사용하셨는데요! AWS 인프라를 활용하는 환경이라면 AWS ALB나 AWS ECR을 쓰고, Terraform 같은 IaC 기술을 활용하면 인프라 구축에 필요한 비용을 많이 줄일 수 있을 것 같다는 생각이 들었습니다. 그럼에도 Docker Hub나 Nginx 인프라를 추가하여 사용한다면 어떤 장점이 있는지 궁금합니다. 실무에선 주로 인프라 구성을 어떻게 하는지도 궁금합니다!
안녕하세요, 이번 강의를 통해 처음으로 헥사고날 아키텍처에 대해서 공부하고 있는 사람입니다. 헥사고날 아키텍쳐를 지키면서 배치, 시큐리티, 이벤트 처리 등등 다양한 기술을 어떻게 사용하나요? 제가 공부해본 바로는 1. 배치: 애플리케이션 계층에 배치를 통해 이루어질 api를 만들어두고, 어댑터 계층엔 배치(Job, Step, Writer, Reader등 )에 관한 설정들을 위치하게 한다. 2. 시큐리티: 전부 어댑터에 위치한다. 이벤트 처리: 이벤트는 도메인으로 간주하고 도메인 계층에 위치시키고, 이벤트 리스너는 어댑터 계층에 위치시킨다. 이벤트를 발행시키는 로직은 애플리케이션 계층에 위치하고, ApplicationEventPublisher 같은 경우는 추상화됐다고 판단하고 그냥 사용하거나, 혹은 인터페이스를 따로 만들어서 사용한다. 이정도인데 큰 흐름에서 제가 이해한 게 맞을까요? 특히 궁금한 건 "이벤트가 도메인으로 간주되어도 문제가 없는지" 입니다. (무조건 도메인이기 보다는 로직을 처리하기 위해 존재하는 dto로 볼 수도 있는 거 아닌가 싶어서요.) 다른 기술들을 헥사고날 아키텍쳐에 적용시킬 때 주의할만한 사항들도 따로 존재를 할까요?
안녕하세요 우선 좋은 강의 감사드립니다. 덕분에 Batch에 대한 기본적인 틀을 잡을 수 있을 것 같아요! 중급강의도 기대됩니다. 실습을 따라가던 와중, 멱등성을 유지하기 위해서 궁금한점이 생겨서 질문드립니다. 같은 파라미터로 완료된 job은 재실행을 허용하지 않기 때문에 parameter로 time을 넣어주셨는데요. 그렇게 되면 만약에 job을 실패지점부터 재실행 하고 싶은 경우에는 targetDate 뿐만 아니라 실패한 시간대에 time 파라미터까지 넣어서 재시작을 해야하는 것인가요? 만약에 time 파라미터를 추가한 상태에서, 이전 실행과 다른 time 파라미터로 완료된 job을 재실행 할경우에는 정산 테이블에서 targetDate에 해당하는 값을 DELETE를 하고 INSERT를 진행해야 멱등성이 유지될 것 같습니다. 이럴 경우 DELETE 같은 경우는 Settlement INSERT 작업 이전에 별도의 Step으로 구성이 되야할까요? 만약에 DELETE를 해야한다면 DELETE의 경우에는 targetDate의 해당 하는 값을 한번에 전부 지우고 INSERT를 시작하는지 궁급합니다..!
강사님 안녕하세요~! 배치 실패시 서버 담당자에게 메일 보여주기 수업 잘들었습니다! 마지막에 실패시 리스너 동작을 테스트 하시기 위해서 예외를 던지신듯 합니다. 그런데 실습 결과가 강사님과 다르게 bootRun FAILED라고 나와서요. (> Task :bootRun FAILED FAILURE: Build failed with an exception.) 사소한 것 같기는 한데 이유가 궁금해서 글남깁니다~ 좋은 하루되세요~~!
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요. 1. 강의 내용과 관련된 질문을 남겨주세요. 2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요. (자주 하는 질문 링크: https://bit.ly/3fX6ygx) 3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요. (질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG) 질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요. ========================================= [질문 템플릿] 1. 강의 내용과 관련된 질문인가요? (예/아니오) 2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오) 3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오) [질문 내용] 여기에 질문 내용을 남겨주세요. 영상에선 정렬되서 나오는데 제 DB에서는 price부터 나오네요 코드 에러는 없고 넣으면 들어가는데 보기좋게 정렬되게 만들고 싶은데 어떻게 해야할까요?
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요. 1. 강의 내용과 관련된 질문을 남겨주세요. 2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요. (자주 하는 질문 링크: https://bit.ly/3fX6ygx) 3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요. (질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG) 질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요. ========================================= [질문 템플릿] 1. 강의 내용과 관련된 질문인가요? (예) 2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예) 3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예) [질문 내용] 현재 최신 버전인 SpringBoot4 + Hibernate7 을 사용해서 강의를 듣고 있습니다. 이 버전에서는 (Hibernate 모듈 등록 X + 프록시 직접 초기화 X] 상태에서 API 응답으로 엔티티를 곧바로 반환하게 되면, 강의 내용처럼 오류(예외)가 나지 않고, Jackson이 json을 만드는 과정에서 getter 등을 호출해서 프록시 객체들을 자동으로 초기화(로딩)시키는 것처럼 보이네요. 응답 결과에서도 모두 출력되고요 (물론, @JsonIgnore 없으면 무한루프는 발생) 그래서 강의 내용처럼 오류가 나도록 하는 방법을 한참 찾다가 현재 버전에서 Hibernate 모듈을 등록하는 방법을 발견해서 공유해봅니다. (메뉴얼에도 없길래) [등록 방법] 1. 라이브러리 등록 implementation 'tools.jackson.datatype:jackson-datatype-hibernate7' 2. 빈 등록 @Bean public Hibernate7Module hibernate7Module() { Hibernate7Module module = new Hibernate7Module(); // module.configure(Hibernate7Module.Feature.FORCE_LAZY_LOADING, true); return module; }
[질문 템플릿] 1. 강의 내용과 관련된 질문인가요? (예/아니오) 2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오) 3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오) [질문 내용] 여기에 질문 내용을 남겨주세요. ============================= 안녕하세요. Spring Data JPA에서 연관관계 필드에 대한 exists 메서드 사용 시, 아래 두 방식 중 어떤 방식이 더 적절한지 궁금합니다. ProjectMember 엔티티는 아래처럼 Project , User 와 연관되어 있습니다. public class ProjectMember { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "project_id", nullable = false) private Project project; @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "user_id", nullable = false) private User user; } 사용자가 특정 프로젝트에 포함되어 있는지 확인하려고 할 때, 아래 두 가지 방식을 테스트해봤습니다. 1. 식별자 사용 : boolean existsBy UserId And ProjectId (Long userId, Long projectId) 단점: 이 메서드를 실행하면, project_members 테이블에 user_id , project_id FK가 있음에도 불구하고 users , projects 테이블과 불필요한 left join이 발생 했습니다. 실행 SQL: select pm1_ 0.id from project_members pm1_0 left join users u1_0 on u1_ 0.id = pm1_0.user_id left join projects p1_0 on p1_ 0.id = pm1_0.project_id where u1_ 0.id = ? and p1_ 0.id = ? fetch first ? rows only; 2. 엔티티 사용 : boolean existsBy User And Project (User user, Project project) 장점: 이 경우에는 조인 없이 where 절에서 FK 컬럼으로 조회 되었습니다. 단점: 하지만, 이 메서드를 사용하려면 서비스에서 userId, projectId 를 이용하여 User와 Project를 추가로 조회 해야 한다는 단점이 있습니다. 실행 SQL: select pm1_ 0.id from project_members pm1_0 where pm1_0.user_id = ? and pm1_0.project_id = ? fetch first ? rows only; 결론: 이 경우 두 방식 중 어떤 것을 사용하는 것이 더 좋은 선택인가요?
[질문 템플릿] 1. 강의 내용과 관련된 질문인가요? (예/아니오) 예 2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오) 예 3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오) 예 [질문 내용] 여기에 질문 내용을 남겨주세요. ============================== 안녕하세요. Spring Data JPA에서 연관관계 필드에 대한 exists 메서드 사용 시, 아래 두 방식 중 어떤 방식이 더 적절한지 궁금합니다. ProjectMember 엔티티는 아래처럼 Project , User 와 연관되어 있습니다. public class ProjectMember { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "project_id", nullable = false) private Project project; @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "user_id", nullable = false) private User user; } 사용자가 특정 프로젝트에 포함되어 있는지 확인하려고 할 때, 아래 두 가지 방식을 테스트해봤습니다. 1. 식별자 사용 : boolean existsBy UserId And ProjectId (Long userId, Long projectId) 단점: 이 메서드를 실행하면, project_members 테이블에 user_id , project_id FK가 있음에도 불구하고 users , projects 테이블과 불필요한 left join이 발생 했습니다. 실행 SQL: select pm1_ 0.id from project_members pm1_0 left join users u1_0 on u1_ 0.id = pm1_0.user_id left join projects p1_0 on p1_ 0.id = pm1_0.project_id where u1_ 0.id = ? and p1_ 0.id = ? fetch first ? rows only; 2. 엔티티 사용 : boolean existsBy User And Project (User user, Project project) 장점: 이 경우에는 조인 없이 where 절에서 FK 컬럼으로 조회 되었습니다. 단점: 하지만, 이 메서드를 사용하려면 서비스에서 userId, projectId 를 이용하여 User와 Project를 추가로 조회 해야 한다는 단점이 있습니다. 실행 SQL: select pm1_ 0.id from project_members pm1_0 where pm1_0.user_id = ? and pm1_0.project_id = ? fetch first ? rows only; 결론: 이 경우 두 방식 중 어떤 것을 사용하는 것이 더 좋은 선택인가요?