묻고 답해요
158만명의 커뮤니티!! 함께 토론해봐요.
인프런 TOP Writers
-
미해결실전! 스프링 부트와 JPA 활용1 - 웹 애플리케이션 개발
한가지 상품이 아닌 여러가지 상품 주문 시
안녕하세요 강사님 강의를 듣다가 여러가지 상품을 주문할 수 있게 구현해보고 싶은데 thymeleaf에서 여러 상품을 선택 했을 시 선택 데이터들을 리스트형태로 만들어서 postMapping에 보내야하는건가요...?그렇다면 thymeleaf문법은 어떻게 들어가야하는지 궁금합니다... (추가적으로 상품을 고르게되면 고른 리스트가 보이면서 더 상품을 추가하거나 삭제하게 할려면 자바스크립트로 설정해두는건가요?!)
-
미해결실전! 스프링 부트와 JPA 활용2 - API 개발과 성능 최적화
totalPrice
안녕하세요 15:48 보시면 totalPrice 값이 나오는데 이 메소드는 언제 호출이 된건가요? 따로 호출해 준적이없는거 같습니다 ========== @GetMapping("/api/v1/simple-orders")public List<Order> ordersV1(){ List<Order> all = orderRepository.findAllByString(new OrderSearch()); return all;} =========== public int getTotalPrice(){ int totalPrice = 0 ; for(OrderItem orderItem : orderItems){ totalPrice+=orderItem.getTotalPrice(); } return totalPrice;}
-
미해결실전! 스프링 부트와 JPA 활용2 - API 개발과 성능 최적화
일대다 페치조인 메모리상에서 페이징
안녕하세요 영한님 강의 잘 듣고 있습니다!! 일대다 페치조인에서 페이징을 하게되면, 메모리 상에서 페이징을 한다고 이해했습니다. 만약 페치조인 쿼리가 DB로 가면, 뻥튀기된 로우들이 메모리에 올라오게 되고 distinct를 JPA가 하게됩니다. 이 상황에서 만약 페이징이 이루어진다면 뻥튀기된 로우에서 offset만큼 결과를 리턴하게 되다고 이해했습니다. 결론적으로 생각하면 뻥튀기된 로우를 페이징하기 위한 쿼리와 전체를 가져오는 쿼리가 같은 상황에서, 왜 메모리상에서 페이징하는 것이 위험한가요?
-
미해결Spring Cloud로 개발하는 마이크로서비스 애플리케이션(MSA)
같은 네트워크에 묶인다는건 물리적으로 같은 Host PC 에 컨테이너가 추가된다는 건가요?
docker network create 명령을 통해 만든 ecommerce-network 상에 컨테이너를 추가하기 위해서는 물리적으로 같은 Host PC에 컨테이너가 존재해야 하나요? 아니면 원격에 물리적으로 다른 위치의 컨테이너도 ip를 추가하여 같은 네트워크로 묶을수도 있는건가요? 강의 마지막 15:17쯤에서 나오는 강의 화면을 보면서 이런 의문이 들었습니다.
-
미해결스프링 입문 - 코드로 배우는 스프링 부트, 웹 MVC, DB 접근 기술
안녕하세요 영한님 @Transactional 및 open에 관하여 질문이 있습니다.
안녕하세요 영한님! 강의 내용을 코틀린 기반으로 작성해보고 있는데요! 조금 다른 부분들이 있긴 하지만 여러 리서치를 해보며 정상 동작하는 것들을 확인했는데 굉장히 특이한 문제를 만나서 조언을 구하고자 질문 드립니다. MemberService의 MemberRepository를 SpringConfig에서 의존성 주입을 해준 뒤 실제 메서드에서 해당 repository를 호출해보니 repository가 null이어서 접근할 수 없다는 메시지와 함께 에러가 발생하였습니다. 이에 대해 조금 조사해 본 결과 @Transactional를 추가하게 되면 구성된 의존성에 접근이 되지 않는 문제가 있었습니다. 그러나 이 생성자에서 받아온 의존성을 open 제한자로 변경하여 받아오면 접근이 되는 기묘한 현상이 발생하더군요! 관련해서 해결책을 찾은 경로는 여기였습니다. https://stackoverflow.com/questions/41298289/spring-boot-autowired-with-kotlin-in-service-is-always-null 혹시 강의 내용과는 조금 차이가 있지만 왜 이런 현상이 발생하는지 알 수 있을까요? 강의 너무 잘 듣고 있습니다. 항상 감사합니다!
-
미해결자바 ORM 표준 JPA 프로그래밍 - 기본편
저는 m = 의 값이 나오지 않습니다 ㅠㅠ
1. persistence.xml2. Member.java package hellojpa;import javax.persistence.*;@Entity // JPA의 관리 대상이 된다.public class Member { @Id @GeneratedValue @Column(name = "MEMBER_ID") private Long id; @Column(name = "USERNAME") private String username;//// @Column(name = "TEAM_ID")// private Long teamId; @ManyToOne @JoinColumn(name = "TEAM_ID") private Team team; public Long getId() { return id; } public void setId(Long id) { this.id = id; } public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public Team getTeam() { return team; } public void setTeam(Team team) { this.team = team; }} 3. Team.java package hellojpa;import javax.persistence.*;import java.util.ArrayList;import java.util.List;@Entitypublic class Team { @Id @GeneratedValue @Column(name = "TEAM_ID") private Long id; private String name; // Team객체에서 Member클래스를 참조하기 위해 @OneToMany(mappedBy = "team") private List<Member> members = new ArrayList<>(); public Long getId() { return id; } public void setId(Long id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public List<Member> getMembers() { return members; } public void setMembers(List<Member> members) { this.members = members; }} 4. JpaMain.java package hellojpa;import javax.persistence.EntityManager;import javax.persistence.EntityManagerFactory;import javax.persistence.EntityTransaction;import javax.persistence.Persistence;import java.util.List;public class JpaMain { public static void main(String[] args) { // 엔티티 매니저 팩토리는 하나만 생성해서 애플리케이션 전체에서 공유 EntityManagerFactory emf = Persistence.createEntityManagerFactory("hello"); // DB커넥션을 얻는 일관적인 행위를 할때마다 EntityManager를 만들어줘야한다. // 엔티티 매니저는 쓰레드간에 공유X (사용하고 버려야 한다) EntityManager em = emf.createEntityManager(); // // JPA의 모든 데이터 변경은 트랜잭션 안에서 실행. EntityTransaction tx = em.getTransaction(); tx.begin(); // 트랜젝션 시작 try { // 저장 Team team = new Team(); team.setName("TeamAA"); em.persist(team); Member member = new Member(); member.setUsername("member22"); member.setTeam(team); em.persist(member); em.flush(); em.close(); Member findMember = em.find(Member.class, member.getId()); List<Member> members = findMember.getTeam().getMembers(); for (Member m : members) { System.out.println("kkk = " + m.getUsername()); } tx.commit(); }catch (Exception ex) { tx.rollback(); } finally { em.close(); } emf.close(); // 웹 애플리케이션에서 WAS가 종료될 때 emf 종료 => release //code em.close(); emf.close(); }} 문제 1. 콘솔창에 kkk = 결과값이 나오지 않습니다. 문제 2. H2 DB에 저장되지 않습니다.em.flush();em.clear(); 를 지우고 했을 때는 저장이 되지만 마찬가지로 결과값은 나오지 않았습니다. em.flush();em.clear();를 붙이니 결과값도, DB에 저장도 되지 않았습니다. 원인 파악 부탁드립니다 ㅠㅠ 디버깅 해보았는데도 잘 모르겠어요 ㅠㅠ
-
미해결자바 ORM 표준 JPA 프로그래밍 - 기본편
시퀀스 전략 중 allocationSize의 아이디어
안녕하세요 영한님! 다름이아니라 제가 이해한 내용이 맞나 궁금해서 질문드립니다. 시퀀스 전략 중 allocationSize에서 이 값이 50이면 시퀀스를 한 번에 50씩 증가하고 그만큼 메모리에 1~50까지 식별자를 할당하는데 50까지 차면(51일 때) 시퀀스 값을 한 번 더 50 증가시켜 100까지 할당하는 방식이라고 하셨습니다. 처음에 조금 헷갈리거나 이해가 안갔던 부분은 시퀀스 값이 1이면 애플리케이션에서 1~50까지 사용하고 시퀀스 값이 2이면 애플리케이션에서 51~100까지 기본 키를 사용하는 건데, 제가 이를 이해한 것은 네트워크시간에 배우는 TCP의 슬라이딩 윈도우 개념과 비슷하지 않나 해서 이와 유사한 아이디어라고 이해하였는데 이렇게 생각해도 되나요??ㅎㅎ; 시퀀스 값 1마다 기본키 50으로 묶이는건 세그먼트와 바이트번호 관계처럼 묶이는(?) 개념이라 생각이 듭니다. 감사합니다 // 슬라이딩 윈도우
-
미해결실전! 스프링 부트와 JPA 활용1 - 웹 애플리케이션 개발
dto 만들 때 질문이 있습니다.
요청이나 응답 dto를 만들 때 엔티티의 임베디드 타입 필드의 경우 다 풀어서 생성해야 하나요? 아님 임베디드 타입 필드 그대로 사용해도 괜찮나요??
-
해결됨자바 ORM 표준 JPA 프로그래밍 - 기본편
일대일: 대상 테이블에 외래 키 단방향 관계를 JPA가 지원하지 않는 이유?
안녕하세요 강사님. 그림으로만 봐서는 일대다 단방향과 비슷한 것 같은데, 왜 일대일: 대상 테이블에 외래 키 단방향 은 JPA가 지원하지 않는지 이해가 잘 안됩니다😭 일대다 단방향 일대일: 대상 테이블에 외래 키 단방향
-
해결됨실전! 스프링 데이터 JPA
역할과 구현
안녕하세요. 방학기간을 통해 스프링에 대해 공부하고 있는 대학생입니다. 다름이 아니라 스프링 핵심원리 강의에서 역할과 구현을 분리하라고 배웠습니다. 그래서 만약 '회원 저장소'를 만든다고 하면 pubic interface MemberRepository{ void save(Member member); Member findById(Long memberId); } 을 만들고 필요한 구현체를 따로 만들었습니다. 메모리를 이용한다면 public class MemoryMemberRepository implements MemberRepository { private static Map<Long, Member> store = new HashMap<>(); @Override public void save(Member member) { store.put(member.getId(), member); } @Override public Member findById(Long memberId) { return store.get(memberId); } } 이런 식으로 만들고, 만약 JPA를 이용한다면 public class MemberJpaRepository implements MemberRepository { @PersistenceContext private EntityManager em; public void save(Member member) { em.persist(member); } public Member findById(Long id) { Member member = em.find(Member.class, id); return member; } } 이런 식으로 만들어서 사용했습니다. 여기서 스프링데이터JPA를 사용하기 위해선 인터페이스에 JpaRepository를 상속받아야하는데 그러면 기존에 있던 MemberRepository에 상속받아서 사용하면 되나요? 그런데 MemberRepository에서 JpaRepository를 상속받게 되면 기존에 MemberRepository 구현체들이 JpaRepository까지 모두 구현해야하는 문제가 있고, MemberReposity에서 사용하는 메소드 이름과 JpaRepository에서 사용하는 메소드 이름이 같으면 MemberRepository를 주입받아 사용하는 다른 클래스에도 문제가 발생했습니다. 이래저래 글이 길었지만 그래서 어떻게 스프링데이터 JPA를 사용하면서 역할과 구현을 구분할 수 있을까요?
-
미해결자바 ORM 표준 JPA 프로그래밍 - 기본편
p.245 상속관계 맵핑 3가지 방법 질문
조인/ 단일테이블 / 구현클래스마다 테이블 이 세가지 전략에 대한 소스코드를 교재에서 확인할 수 있는데요 세 전략 모두 Item 클래스를 추상클래스로 선언했음에도 아래와 같은 차이를 보입니다. '조인' / '단일테이블' 의 경우에는 ITEM 테이블이 생성된 반면,[그림7.3, 그림7.4] '구현클래스마다 테이블'에서는 ITEM 테이블이 생성되지 않는 것으로 이해되고 있습니다.[그림 7.5] 왜 이런 차이를 발생시키는 것인지 궁금합니다. 별개로, 강의에서는 '조인'/'단일테이블' 설명하실 때 Item클래스를 추상클래스로 선언하지 않으셔서 이 부분도 혼동을 주고있습니다.
-
해결됨실전! 스프링 부트와 JPA 활용1 - 웹 애플리케이션 개발
주문취소 테스트시
주문취소쪽 테스트하다가 궁금한점 있어 질문드립니다. 취소할 주문ID를 조회하고 Order order = orderRepository.findOne(orderId); order.cancel(); 로 주문취소하기 전에 orderItems에 값이 넣어져 있는지 모르겠습니다. Order와 OrderItem은 @OneToMany로 기본이 LAZY 로딩이라 orderItems을 직접 호출하기 전까지는 데이터를 조회하지 않는거로 알고 있는데 어떻게 orderItems에 값이 채워져서 취소가 되는지요?... for (OrderItem orderItem : orderItems) { orderItem.cancel();} 저 for문 시점에 데이터를 조회하면 이해하겠는데 디버깅해보면 order를 조회할때 이미 값이 다 채워져 있습니다...
-
미해결실전! 스프링 부트와 JPA 활용2 - API 개발과 성능 최적화
커맨드와 쿼리의 구분 후 쿼리문 한번 더 실행에서의 궁금증...
강의에서 영한님께서는 커맨드와 쿼리를 구분하는 것을 선호하신다고 하셨습니다. 그래서 알아보니 이런걸 CQRS라고 하던데 회원 정보를 update시 update command 메소드 실행 후 보통같으면 update메소드 자체의 반환값으로 member객체나 member id를 받는데, 이것을 명령과 질의를 구분해 memberService.update() 후 memberService.findOne을 실행하면 결과적으로 쿼리문을 한번 더 실행을 하게 되잖아요? update 메소드 내에서도 findOne이라는 메소드를 호출하니깐요. 이렇게 명령과 질의를 분리하였지만 그 대가로 쿼리문을 한번 더 호출하게 된 셈인데 쿼리문을 한번 더 호출해서 명령과 질의를 구분하는 것이 많이 효율적인 패턴인가요?
-
미해결자바 ORM 표준 JPA 프로그래밍 - 기본편
영속성 컨텍스트와 트랜잭션 관련 질문 있습니다.
안녕하세요 JPA 를 공부를 하다가 영속성 컨텍스트의 기본 전략은 트렌잭션 범위라고 알고 있어 테스트 코드를 작성해 실행해 본 결과 아래와 같은 코드에서 select 문이 안 나가는 걸 볼 수 있었습니다.select 문이 안 나가는 것은 영속성 컨텍스트 안에서 가져온 객체라고 볼 수 있는데 save와 select 가 각각 다른 트랜젝션 단위에서 작동을 하는데 왜 이런 결과가 나오는 건가요..? 테스트 코드 git 주소 첨부드립니다. ( test3 메소드 )깃 주소 @Test @DisplayName("영속성 컨텍스트 1차 캐시 - 트랜잭션이 다른 경우 - 1차 캐시 사용 불가") void test3() throws Exception{ User user = User.builder().nickname("유저 1").build(); save(user); // 트랜잭션 1 //select 문이 나가야 함 // 트랜잭션 2 User findUser = find(user.getId()); //다른 객체라고 나와야하는데 select 문이 안나가고 같은 객체가 나오는 걸 보니 영속성 컨텍스트 안에서 동작 중임 log.info("{} - {}",user.hashCode(), findUser.hashCode()); assertThat(user, is(not(equalTo(findUser)))); } @Transactional(propagation = Propagation.REQUIRES_NEW) void save(User user){ userRepository.save(user); } @Transactional(propagation = Propagation.REQUIRES_NEW) User find(Long id) throws NotFoundException { return userRepository.findById(id).orElseThrow(() -> new NotFoundException("not found Exception")); }
-
미해결자바 ORM 표준 JPA 프로그래밍 - 기본편
선생님 안녕하세요 abstract 를 붙히는 이유을 좀 여쭤볼 수 있을까요??
Item 엔티티에 abstract를 붙히는 것과 안붙히는 것의 차이를 좀 여쭤볼 수 있을까요?... .. abstract를 붙히신 이유를 좀 여쭙고 싶습니다..
-
미해결실전! 스프링 부트와 JPA 활용1 - 웹 애플리케이션 개발
Update 할 때 조건검사(price >= 0) 는 어디서 하는게 좋은 방법일까요?
안녕하세요. 너무 좋은 강의 잘 듣고있습니다 !! :) 강의 마지막부분에서 가장 좋은 방법이라고 말씀해주신대로, Service 계층에 ItemUpdateDto 를 추가하고, 엔티티 클래스에 update() 함수도 만들어서 구현을 했습니다. 여기서 한 가지 궁금한점이 생겼는데요, - price >= 0 - stockQuantity >= 0 - name 은 빈 문자열이 아님(StringUtils.hasText == true) 등의 조건을 검사하여 exeception 을 날리거나, update 를 진행하고 싶을 때 조건검사를 어디서 하는 것이 가장 좋은지 고민이 됩니다. 제 생각에는 크게 세가지 방법이 있을 것 같은데요.. 1. Controller 에서 검사하여, 검증된 값만 DTO에 담아서 service 에 전달한다. 2. service 에서 엔티티의 update() 함수를 호출하기전에 검사한다. 3. 엔티티 클래스의 update() 함수 내부에서 검사한다. 세 가지 방법에대해 제가 고민해본 내용을 말씀드리면.. Book 클래스의 removeStock() 처럼 엔티티 내부에서 검사하고, NotEnoughStockException 같은 에러를 날리는 비지니스 로직을 넣어야할까요? (코드에 일관성이 있도록..) --> 3번 그런데, Controller 에서 미리 검사를 하면 굳이 service -> repository 를 타고 내려가서 select 쿼리를 날릴 필요가 없어지기 때문에 성능상 유리할 것 같다는 생각도 듭니다. --> 1번 두 군데에서 다 검사를 하는 것이 좋을까요? 실무에서는 보통 어떤 방법을 채택하는지 궁금합니다 .
-
미해결자바 ORM 표준 JPA 프로그래밍 - 기본편
상속관계매핑 중 JOINED 질문드립니다.
※ 참고 : MySQL DB 를 사용하고 있습니다. 아래 사진처럼 SecureSetting, SessionTimeoutSetting 2개의 엔티티를 JOINED 전략을 이용해 상속관계 매핑을 해주었습니다. 그런데 3번째 사진처럼 테스트 코드를 작성하고 실행한 결과, ss_configuration 테이블에는 데이터가 잘 들어가는데 ss_session_timeout 테이블에는 데이터가 들어가지 않습니다. 쿼리로 로그 찍힌걸 봐도 insert 쿼리는 2번 나간것을 확인하였습니다. 혹시나 싶어서 SecureSetting 클래스의 @Id 전략을 AUTO 로 바꾸고 하면 잘 되었습니다. JOINED 전략에서는 Id 전략 중 IDENTITY 전략을 사용할 수 없나요?
-
미해결스프링 입문 - 코드로 배우는 스프링 부트, 웹 MVC, DB 접근 기술
jpa 를 사용하고 회원가입 부분을 돌리는 도중에 에러가 발생했습니다
에러가 났는데 어느부분을 확인을 해야될지 모르겠어요 ㅠ 어느부분 확인해야될까요??
-
미해결실전! Querydsl
JPAQueryFactory 빈등록
JPAQueryFactory를 매번 Repository마다 만들지 않고 빈으로 등록해서 사용하면 안 되나요??
-
미해결실전! 스프링 부트와 JPA 활용1 - 웹 애플리케이션 개발
thymeleaf, cannot resolve vars 에러 문제
이런식으로 에러가 떠서 구글링을 해보니 다양한 해결책이 있긴한데 그것이 옳은 방식으로 해결되는 것인지 모르겠습니다 <html xmlns:th="http://www.thymeleaf.org"> 여기에서 www를 삭제하면 th: 라인이 전부 초록색으로 변하면서 에러는 해결되기는 하더라고요 다른 해결 방식이 있을까요?