Geforce Experience가 설치된 분들에 한해서 Ctrl + Alt + M(Extract Method) 단축키가 작동하지 않는 오류를 발견했습니다. Geforce Experience를 켜고 설정에서 빨간색 네모 친 게임 내 오버레이 기능을 OFF하시면 단축키가 잘 작동할 것입니다!
안녕하세요 기선님 좋은 강의 감사드립니다!! :) 흐름을 살펴보니 csrf필터를 거치는 요청의 경우 csrf 토큰이 없는 경우 csrf 토큰을 생성해서 요청을 반환하고, 폼요청을 보낼 때, 반환받은 csrf토큰을 같이 보내는 것 같은데, 그럼 서버쪽에서는 생성해준 csrf 토큰의 값을 어디서 보관하고 있는건가요? csrf 토큰을 포함한 요청이 왔을때 비교를 하기 위해선 반환한 토큰값을 서버측에서도 어디선가 유지하고 있어야 할텐데 그 부분이 어디일지 또 언제까지 유지하는지 궁금해서 질문남깁니다!! ======================= 질문을 남기고 구글링을 통해 찾아본 결과는 CsrfTokenRepository를 사용해서 토큰정보를 가지고 있는 것같은데 기본구현체는 HttpSessionCsrfTokenRepository를 사용하는 것으로 보아 Session을 기반으로해서 토큰 정보를 유지하고, session이 사라지면 자연스럽게 토큰 정보도 날라가는것 처럼 보이는데 맞을까요?
안녕하세요 강의 잘 듣고 있습니다 ^^ jpa와는 관련이 없는 질문인데 강의를 보면 List<Child> childList = new ArrayList<>(); addChild(Child child) { childList.add(child) } 이 부분이 있는데 add가 자주 발생하면 LinkedList가 좋다고 이해했는데 초기 리스트는 업무에 따라서 ArrayList나 LinkedList를 선택해서 생성하나요? 아니면 보통 ArrayList를 무조건 사용하나요?
안녕하세요 강사님! 테스트 수행 중 application.yml 파일을 test 밑에 두고 따라하는중에 application.yml 파일을 찾지 못하고 자꾸 main 밑에있는 파일을 불러왔습니다. 찾아보니 test/resources/config/application.yml 로 두어야 인식한다고 되어있고 저도 config 디렉토리를 생성해 그 밑에 두었더니 별도의 application.yml 파일로 읽어오더라구요. https://stackoverflow.com/a/53134737 인텔리제이로 학습중인데 이부분 한번 확인 부탁드리겠습니다!
챕터 1,2 건너뛰고 챕터 3부터 들으려고 합니다. 근데 프로젝트 만드는건 각자한다해도 안에 기본적인 컨트롤러나 뷰계층 파일들 다 만들어져있는 상태에서 강의 진행하시는데 이건 각자 알아서 만드나요? 깃허브 주소 공유해주신건 완성본인데 여기서 필요한것만 가져와서 플젝을 만들어야하나요?
13:43 부분을 보면 JPA 는 내부적으로 리플렉션을 통해서 객체를 생성하기 때문에 기본 생성자가 필요하다고 하셨는데요. 다음과 같이 기본 생성자는 생성하지 않고 코드를 돌리더라도 문제없이 돌아가던데, 내부적으로 기본생성자가 없더라도 동작하도록 변경이 된걸까요.? 추가) 추가적으로 강의를 진행 하던 중에 em.find() 로 실행하니 이제는 디폴트 메소드가 없다고 에러메시지가 출력이 되네요. persist() 할 때는 출력되지 않던 에러가 find() 에서는 출력되는데 어떤 메커니즘 차이 때문에 이런 결과가 발생하는 건가요.?
안녕하세요 따로 공부하다가 궁금한 점이 생겨서 질문 남깁니다. item에서 InheritanceType . JOINED 를 사용하게 되면 화면에서 컨트롤러로 Form data를 받아와서 처리하는 로직은 어떤식으로 구현을 하는게 효과적인가요? 예를들면 formData에 타입을 넣어줘서 if else문으로 각각에 맞는 Controller(formData){ if(formData.getType equals "B") persist( new B(formData.a formData.b , formData.c)) else if ("A") persist( new A(formData.dd formData.gg ) else if ~~~~ } 이런식으로 전부 빼야 하나요?? 만약 위와 같은 상황이라면 타입이 엄청나게 많아지는 경우 무한if else을 쓰기는 좀 비효율적인 코드가 될 거 같아서 질문드립니다.
혹시, application.properties 를 통해 기본유저 정보를 변경하고 동작이 잘 되지 않으시는 분들은 크롬 프라이빗 모드로 캐시를 날리고 해보세요! 한 시간 가까이 해맸는데, 크롬 프라이빗 모드로 하니 제대로 동작하네요! 첫 강의에서 개발할때 해당 모드를 사용해서 하는게 편하다고 하셨는데 그 이유를 절감했네요 ...
안녕하세요. 다른 사람이 만든 DB의 데이터를 가져와서 가공하여 제공하는 API를 만들려고 합니다. spring data jpa + querydsl 환경이고 읽기전용 entity를 만들려고 합니다. 기본편도 들었지만 entity를 만들면서 db도 생성되었기에 읽기전용 entity를 어떻게 만드는지 혹여나 컬럼 혹은 데이터 수정이 되지 않을지, entity를 만들때 모든 컬럼을 다 정의해야되는지 등의 개념을 파악하기가 힘듭니다. 검색해봐도 잘 나오지 않네요. 혹시 답변 가능하실까요? 참고할만한 사이트 혹은 개념이라도 알려주시면 찾아서 해보겠습니다. 감사합니다.
안녕하세요 Eclipse 환경에서 강사님 강의를 따라하고 있습니다. MemberServiceIntegration.java의 테스트가 불가능하고 " The input type of the launch configuration does not exist "라는 오류가 뜹니다. 찾아보니 intellij에선 상관없지만 eclipse에서 발생하는 문제이며, source folder로 등록되어 있지 않기 때문에 발생한다고 하는데 build path 통해서 확인해보니 사진과 같습니다. 존재하긴 하는데 다른 폴더들과 달리 진하게?? 되어있어 source folder로 등록되어 있는 것이 맞는지 의문입니다. gradle 환경에서 따로 source folder를 강제로 등록시키는 방법이 있을까요??
안녕하세요 강사님. 기본강의에서도 연관관계 메소드를 공부하여 알고 있었습니다. 양방향 연관관계에서 주인이 되는 쪽을 수정하면 주인이 아닌쪽에서도 자동으로 수정이 되지만 객체의 개념으로 접근하기 위해 양쪽을 모두 수정해주는 연관관계 메소드가 필요한것인가요? 주인이 되는 쪽만 잘 수정해주면 사실상 연관관계 메소드가 필요 없는 것이지요? 그렇다면 changeTeam 연관관계 메소드를 이용해서 팀을 바꾸었을때 바뀐 팀의 멤버를 추가하는 것이 맞다면 반대로 바뀌기 전의 팀에서도 멤버를 제거해야되는것이 아닌가요? 예를 들어서 팀1 -> 멤버1 팀2 -> 멤버2 에서 멤버1을 팀2로 옮길시 연관관계 메소드는 add만 해주시기때문에 팀1 -> 멤버1 팀2 -> 멤버2, 멤버1 로 되어 제거를 해주어야 한다고 생각합니다. 하지만 테스트 결과 주인이 되는 쪽을 수정하니 자동으로 멤버1이 제거가 되더군요. 이 또한 객체의 개념을 살리기 위해 제거가 자동으로 되지만 제거가 되는 remove()를 추가해줘야 할까요?
갑자기 궁금증이 생겨 질문드립니다. 벌크 연산은 member2에 age를 +1시켜줍니다. 이떄 db에 쿼리가 넘어가서 db상에 member2 age는 5가되고 영속성컨테스트안에 member2 age는 4가 그대로 유지됩니다. 이 상황에서 플러쉬를 하면 왜 변경감지가 일어나지 않나요? Member member1= new Member( "member1" , 2 ,null ) ; Member member2= new Member( "member2" , 4 ,null ) ; memberJpaRepository .save(member1) ; memberJpaRepository .save(member2) ; int i = memberJpaRepository .bulkAgePlus( 3 ) ; em .flush() ;
리포지토리를 분리하신다고 하셨는데 1. 정말 간단한 쿼리는 스프링 데이터 JPA 리포지토리에서 구현, 쿼리메서드 기능들을 이용하고 조금 복잡하고, 강의에서 설명해주신 다양한 이유에 해당하면 사용자 정의 리포지토리를 구현해서 사용하고 더 복잡한 동적쿼리들은 따로 클래스를 만들어서 총 3개의 리포지토리를 운영하게 되는건가요? 2. 서비스와 리포지토리는 1:1로 매핑하는게 좋다고 들었는데 그럼 3개의 서비스클래스도 따로 만드나요? 3. 핵심 비즈니스 로직과 단순 화면 관련 로직도 구분은 서비스계층에서 이루어지나요? 그럼 하나의 서비스에서 두개의 리포지토리를 접근해도 괜찮나요?? 아직 아키텍처를 고민할만한 실력은 아니지만 궁금점이 해결되지 않아 질문남깁니다..
안녕하세요 기선님 항상 좋은 강의 감사드립니다! 매 영상마다 질문을 남기는 것 같아 죄송하네요.. 비동기 쿼리에 대한 내용을 제 나름대로 요약해서 해석해보려 노력중인데 곡해가 있을까 걱정이 되어 이렇게 글을 남깁니다. 비동기 쿼리를 사용하는 것을 보니, 쿼리를 날리고 데이터를 받아오기 전까지 메인 쓰레드를 놀리지 않기 위해 비동기 쿼리를 사용하는 것으로 보입니다. 그런데 Future 을 사용하면 결국 get 으로 받아오는 작업에서 메인쓰레드가 블로킹이 되니까 Future 보단 콜백메서드를 사용할 수 있는 ListenableFuture 을 사용하는 걸 추천하신거라고 이해 됩니다. 그렇다면 여기서 조금 쓸모없는(?) 작업이긴 하지만 Future 의 get 을 받는 Thread 를 직접 구현해도 되겠다는 생각도 듭니다. 그리고 비동기 쿼리에 대한 테스트 코드 작성이 어려운 이유는 테스트의 특성상 위 테스트는 작업 전체가 한 트랜잭션이 될 테고, save 된 데이터를 가져오기 위한 쓰레드가 작업을 마치기도 전에 메인쓰레드가 끝나버리면서 하이버네이츠의 DB에 변화를 가져오지 않는 쿼리는 날리지도 않는 특성에 의해 insert 쿼리 조차 날라가지 않는 테스트가 되는 거구요. 의도적으로 flush() 를 통해 insert 를 할 수 는 있으나, insert 와 같은 트랜잭션 안에서 시작된 select 쿼리는 그 트랜잭션 내에서 insert가 된 데이터를 인지할 방법은 없게 된다는 설명으로 이해했습니다. 그렇다면.. 테스트를 위해서 @BeforeEach 를 통해 데이터를 먼저 집어넣은 상태로 동작을 확인할 수 있진 않을까 했지만, 이 작업자체도 DB의 변화를 일으키는 작업이 아닌만큼 하이버네이츠가 insert 를 날리지조차 않더군요. 그래서 위 코드에서 flush()를 추가하여 insert를 날렸지만.. 결과는 이렇더군요... 그런데 제 나름대로의 해석으로는 마지막 결과가 조금 이해가 되지 않네요.. 데이터를 집어넣었고 select 를 하는게 보이는데, size 는 0 이뜨고 근데 또 테스트는 성공하네요.. @BeforeEach도 결국은 한 트랜잭션안에서 동작하여 기존의 테스트 코드처럼 내부에서 Comment를 insert 하는 것과 동일한 작업인것인지.. 근데 또 테스트는 어떻게 성공한건지... 어디가 잘못된걸까요? 또 만약,, 제가 이상하게 이해한 부분이 있는 것 같다면 알려주시면 너무 감사하겠습니다!!
안녕하세요 영한님. 강의를 참고하여 프로젝트를 진행 했는데 문제가 발생해서 질문드립니다. 관리자(admin)가 item 테이블의 데이터 하나를 삭제하려고 할 때 해당 item을 주문한 orderItem이 존재하여 외래키 제약 조건 위반이 발생하여 삭제를 하지 못하는 경우,(제가 의도한 설계는 아닙니다) 어떤 식으로 해결 해나가야 할지 감이 잘 잡히지 않네요. JPA에 외래키 제약 조건이 발생하더라도 강제로 삭제를 진행하는 옵션이 있다면 해당 옵션을 걸어줘야 하는지, 아니면 애초에 설계를 orderItem이 있다면 해당 item은 삭제가 안되게 설계를 해야하는건지 영한님이라면 어떻게 해결하실지 궁금합니다..ㅠㅠ
언제나 좋은 강의 감사합니다 기선님! 13분 부터의 설명을 잘 이해하지 못해서 ㅠㅠ 이렇게 질문을 남깁니다. Spring AOP 의 경우 클래스를 빈으로 등록할때, AOP를 적용시킨 Proxy bean이 등록된다고 이해하면 되는걸까요? 궁금한점은, AOP 가 적용되지 않은 A 클래스도 Bean 으로 컨테이너에 들어가고 AOP를 적용한 proxy Bean도 컨테이너에 들어가게 되나요? 중복적인 부분이라 불필요한 리소스 낭비가 일어날거같은데 proxy Bean만 컨테이너에 들어가게 되는게 맞을까요?
다대일 관계에서 다쪽에 편의 메서드가 존재하는 경우 아래처럼 setter없이 =연산자와 add메서드를 통해 설정이 가능합니다. public class Member { private Team team ; public void setTeam ( Team team ) { this . team = team ; team . getMembers ( ) . add ( this ) ; } // ... } 그런데 일쪽에 편의 메서드가 사용되면 public void addOrderItem (OrderItem orderItem) { orderItems .add(orderItem) ; orderItem.setOrder( this ) ; } 이런식으로 setter를 사용할 수밖에 없습니다. (물론 위에 set팀도 setter메서드를 정의한 것이긴 하지만) 제가 이런 질문을 하는 이유는 영한님께서 강의마다 하시는 말씀중에 setter은 가능하면 열어두지 말고 따로 비즈니스 로직을 위한 메서드를 정의해서 사용하는 것이 좋다고 하셨기 때문입니다. 하지만 연관관계 편의 메서드를 위해서는 setter가 필수불가결해보이는데, 이렇게 부분적으로 열어두는 경우는 괜찮은 것인지요?
안녕하세요 김영한 강사님! 먼저 좋은 강의 만들어주셔서 감사합니다! 강의를 듣다가 cascade 관련하여 질문이 생겨서 질문 작성을 하게 되었습니다. 먼저 밑에 분이 먼저 해주신 질문과 강사님의 답변을 보고 cascade 옵션 자체는 연관관계 주인, 양방향등 관계 없이 1. 동일한 라이프 사이클, 2. 참조하는 주인이 private owner 일 때 라고 2가지 조건을 충족할 때 쓴다고 이해하게 되었는데, 그럼 order, orderItem, delivery에서 orderItem과 delivery가 각각 order만 참조하는, 다른 것이 참조할 수 없는 private owner인 건가요? private owner 라는 말에 대한 이해가 정확하게 되지 않아서 질문을 드립니다. 제가 이해한 것이 맞는 건가요? 감사합니다.
강사님 안녕하세요. 강사님 덕분에 JPA 로드맵 강의를 알차게 배웠습니다. 갑자기 뜬금없이 생각났는데 컨트롤러에서 Pageable를 바로 사용할 경우 max size를 제한할 수 있는 방법은 없는건지요. 악의적으로 query String에 size값을 100000000 이렇게 찍어놓고 막무가내로 요청을 여러번 보낸다면 왠지 서버가 뻗을 것 같다는 생각이 들어서요. Pageable에서 최대 사이즈 막을 수 있는 방법이 없다면 따로 VO를 통해서 제한해 줘야하는 건지 궁금해서 질문드립니다.