묻고 답해요
158만명의 커뮤니티!! 함께 토론해봐요.
인프런 TOP Writers
-
미해결실전! 스프링 부트와 JPA 활용1 - 웹 애플리케이션 개발
테스트 실행 시 생성되는 로그의 DDL문에 대해 질문합니다.
안녕하세요 강사님. 테스트를 실행했을 때 강사님께서는 DDL문이 한 줄마다 줄바꿈되어 나오는데, 저는 한줄로 쭉 연결되어 나옵니다. 사실 별 건 아니지만 가독성이 떨어져서 찾아보기가 약간 힘들게 느껴져서 혹시 설정하는 방법이 있는지 여쭤봅니다 ㅠㅠ 현재 H2 버전을 1.4.199를 깔아 사용하고 있는데 이거때문일까요?
-
미해결실전! 스프링 부트와 JPA 활용1 - 웹 애플리케이션 개발
제대로 이해한 게 맞을까요? + 오타 제보 + setter 추가 질문
수정하려는 엔티티의 키가 10이라고 했을 때, 1. DB에는 아직 수정 전인 엔티티가 들어있음. 이건 영속. 2. Book book = new Book(); 한 후 BookForm의 정보들로 set해줌. 이건 그냥 함수 내에서 new로 만들었을 뿐이니 JPA가 관리하고 있지 않음. 하지만 이 book의 키값인 10은 디비에 저장되어있음. 그래서 이건 준영속. (즉, 10이란 키값을 갖는 엔티티에 대해 영속 엔티티와 준영속 엔티티가 동시에 존재하는 상황.) 3. 여기서 준영속 엔티티 book의 key값으로 검색하여 영속 엔티티 findItem을 가져오고 값을 덮어씌움. 4. 모든 작업 이후에도 book은 여전히 준영속 엔티티이므로 더이상 사용하지 않는 것이 좋음. + 5. 결국 더티체킹 메서드를 직접 만들든, em.merge()를 사용하든 내부적으로는 전부 더티체킹을 사용하여 update하는 것임. (null 업데이트 문제는 제쳐두고) 이런 흐름이 맞나요? merge의 과정보다도 merge 실행 전에 같은 키값의 영속,준영속이 동시에 존재하는 부분이 맞는지가 더 모르겠고 궁금하네요. 감사합니다!ㅡㅡㅡㅡㅡㅡㅡㅡ19:53에서 맨 윗줄에 '재'한적이다 오타 제보드립니다. ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ (추가질문) setter를 경계하라는 말씀을 다시 한 번 해주셨는데요. "change()처럼 엔티티에 변경 메서드를 따로 만들면 추적이 쉽다" 라는 말씀에서 이해가 좀 안 가는 부분이 있습니다. setter로 변경을 하더라도 그 setter명으로 역추적하면 변경지점이 어디인지 알 수 있는 것 아닌가요? 혹시 여러 엔티티에서 같은 이름의 멤버변수를 가지는 경우엔 setter이름도 같아져서 찾기 어렵다는 말씀이신가요?
-
해결됨실전! 스프링 부트와 JPA 활용2 - API 개발과 성능 최적화
일대N 컬렉션 페치 조인시의 페이징이 '불가능'?
안녕하세요. 영한님은 강의에서 컬렉션 페치 조인으로는 페이징이 불가능하다고 말씀하셨는데요, 빌드와 실행까지는 어쨌든 되니 불가능하다는 표현은 좀 안맞지 않을까요? 다만, 매우 위험하고 의도한 결과를 못낼 수 있기 때문에 사실상 쓰지 않는 것이 좋다 정도로 이해하는 게 적절한 것 같아서 소견을 말씀드리고 여쭙습니다. _ _;; 읽어 주셔서 감사합니다.
-
해결됨실전! 스프링 부트와 JPA 활용1 - 웹 애플리케이션 개발
null 값 부분에서 오류를 못 찾겠습니다.
안녕하세요~~!! 김영한 선생님!! 강의를 듣다가 해결이 되지 않아서 질문 하나 드리겠습니다. <질문> ItemRepository 부분의 save 메소드 안에 Item.getId() == null이 "Operator '==' cannot be applied to 'long', 'null'"오류 메세지가 나옵니다. 항상 좋은 강의로 보답 해주셔서 감사합니다. 코로나 조심하시고 다음 강의 기대하겠습니다.
-
미해결Spring Boot JWT Tutorial
Spring Data JPA 'findOneWith...'에 대해...
좋은 영상 감사합니다. 저는 최근에 스프링부트, jpa를 시작한지 얼마되지 않아서 아직 모르는 부분이 많아서 질문 올립니다. 저는 jpaRepository에서 조회할 때 주로 'findBy...'를 많이 이용하는데요, 이 영상에서 'findOneWith...'라는 명령어를 처음 보았습니다. 질문드리기 전에 먼저 구글링이나 직접 이용해 보려는데, 정보도 안나오고 Spring Data JPA 의존성에도 인식을 못하는 것을 보면, jpaRepository에서 직접 정의를 하신 것인가요? 굳이 '...With...'이란 수식어를 붙이신 이유가 무엇인가요??
-
해결됨실전! 스프링 부트와 JPA 활용2 - API 개발과 성능 최적화
내부 클래스 질문
안녕하세요 선생님! 바쁘신데 이곳저곳 여러번 질문드려 죄송합니다. 강의를 복습하다가 정말 궁금한게 생겨서요.. Request Dto는 인자로 받아야돼서 테스트같은 곳에서 직접 생성해야하 되기 때문에 static으로 선언했고, Response Dto 같은 경우에는 그럴 필요가 없기 때문에 non-static으로 선언했다고 이해했습니다. 그런데 이런 경고가 뜨길래 찾아봤더니 이펙티브 자바에서 메모리 문제나 gc 문제 떄문에 바깥 인스턴스에 접근할 일이 없다면 무조건 static을 붙여서 정적멤버 클래스로 만들라고 되어있습니다. 실제 프로젝트나 실무에서는 reponse dto처럼 외부에서 직접 생성할 일이 없어도 static inner class로 선언해야 될까요? 정말 감사합니다.
-
미해결실전! 스프링 부트와 JPA 활용1 - 웹 애플리케이션 개발
@Transactional을 Service에서 처리하는 이유?
@Transact ional의 사용 이유에 대해서는 이해가 되었습니다만, 왜 굳이 Service에서 그 처리를 해주는지 이유를 모르겠습니다. 개인적인 생각으로는 직접적으로 em을 사용하는 Repository에서 해주는 게 더 적절하지 않을까 싶습니다. Service에서 사용해야만 하는 특별한 이유가 있을까요?
-
미해결자바 ORM 표준 JPA 프로그래밍 - 기본편
상속관계매핑 Item 클래스의 abstract 관련질문입니다.
선생님 다른 학생 질문의 답에서 다형성 개념을 생각하면 3가지 방법다 ITEM 클래스를 abstract로 생성하는 것이 맞다라고 하셨는데 TABLE_PER_CLASS 옵션만 abstract 를 했을때 ITEM 테이블이 생성되지 않고 나머지 옵션들은 생성이되는데 그냥 그러려니 넘어가면 될까요? 혹시나 해서 album, movie, book 클래스에서 @Entity를 지우고 실행해봐도 결과는 동일 했습니다.
-
미해결자바 ORM 표준 JPA 프로그래밍 - 기본편
일반조인 m,t 와 패치조인 m
https://www.inflearn.com/questions/164472 위의 질문 그대로 입니다! 답변에 궁금한 점이 생겨서 질문 드립니다.=== 영한님 답변 === 이렇게 하면 쿼리는 같지만 결과를 분리해서 받게 됩니다. fetch join을 사용하면 객체 하나로 깔끔한 객체 그래프를 받을 수 있습니다. fetch join의 핵심은 성능 최적화 + 객체 그래프 입니다. ======결과를 분리해서 받게 된다는게 어떻게 받는다는 건지 이해가 잘 안갑니다. 패치조인을 사용하면 일반조인을 사용하면 이렇게 리스트 안에 받는 타입이 Member로 받느냐 Object로 받느냐라는 차이가 있는데 이걸 말씀하시는 걸까요? 추가로 이렇게 각자 받는거보다 객체 그래프로 받았을때의 장점이 더 있을까요?
-
미해결실전! 스프링 데이터 JPA
데이터 중심 테이블 설계와 객체 중심의 테이블 설계
안녕하세요 김영한 스승님. JPA를 공부하다가 갑자기 궁금한게 생겨서 질문드립니다. 객체 중심의 테이블 설계와 데이터 중심의 테이블 설계가 차이점이 어떤것인가요? RDB도 객체처럼 테이블을 만들 수 있는데 그러면 굳이 객체중심으로 테이블을 설계할 필요가 없는거 아닌가요? 이 부분이 너무 헷갈려서 질문드렸습니다...
-
미해결실전! 스프링 부트와 JPA 활용1 - 웹 애플리케이션 개발
변경 감지와 cascade 질문
안녕하세요, 공부하다 cascade 옵션과 변경 감지에 혼동되는 점이 있어 질문 드립니다. 주문 생성 메서드(order)의 경우, Order -> OrderItem / Order -> Delivery가 Cascade 설정이 되어 있어 orderRepository.save(order)만 하더라도 연관된 OrderItem과 Delivery가 각각 Insert된다고 이해했습니다.(remove, detach 등등 모두 동일) 주문 취소 메서드(cancelOrder)를 보면 orderId를 통해 order를 조회하고(조회된 order는 영속 상태), order.cancel()시 orderItem.cancel()과 그 안의 item.addStock()을 통해 변경감지가 되어 order와 item의 update 쿼리가 실행된다고 하셨습니다. 여기서 제가 헷갈리는 부분은 주문 취소시 item이 변경감지가 되어 update쿼리가 실행되는 부분인데요. item.addStock()을 통해 item의 update 쿼리가 실행됐다는 것은 item이 영속성 컨텍스트에 영속상태가 되었다는 것을 뜻하는데, 단순히 order를 orderRepository로 조회를 하게 되면 order와 연관된 모든 엔티티들이 영속상태가 되는 것인가요? (order 한 개 조회 시-> orderItem... 영속-> item... 영속) 위의 과정이 맞다면 연관된 여러 엔티티의 변경감지는 cascade 설정과는 무관하게 엔티티 조회 시 관련된 엔티티는 모두 영속화 되는 것인지 궁금합니다. (order -> orderItem -> item 의 변경감지를 위해 order->orderItem cascade.ALL 설정 & orderItem->item cascade.ALL 설정이 되어야 orderRepository를 통해 order 조회 시 하위 엔티티들이 모두 영속화 되는 것인가?) 만일 연관관계가 있는 엔티티들이 cascade설정이 되어있어야 모두 영속성 상태로 변하는 것이라면 order->orderItem에는 cascade.ALL 설정이 있으나 orderitem->item에는 cascade.ALL 설정이 없는데 order -> orderItem -> item 순으로 변경감지가 되는지 궁금합니다. 질문이 좀 길어졌는데요 변경감지와 cascade 두 개념에 혼동이 와서... 위 질문에 답변해주시면 감사하겠습니다!
-
미해결실전! 스프링 데이터 JPA
페이징 질문
안녕하세요 선생님! 강의를 듣다가 궁금한게 생겨 몇 가지 질문드립니다. 1. @Query를 이용해서 jpql 페치조인을 한 경우, 페이징을 하려할때 다음과 같은 에러가 뜹니다. @Query("select m from Member m join fetch m.team") Page<Member> findFetchJoinTeam(Pageable pageable); @Testvoid member(){ Team teamA = teamRepository.save(new Team("teamA")); memberRepository.save(new Member("member1", 40, teamA)); memberRepository.save(new Member("member2", 40, teamA)); memberRepository.save(new Member("member3", 40, teamA)); PageRequest pageRequest = PageRequest.of(0, 3, Sort.by(Sort.Direction.DESC, "username")); Page<Member> fetchJoinTeam = memberRepository.findFetchJoinTeam(pageRequest);} Failed to load ApplicationContext java.lang.IllegalStateException: Failed to load ApplicationContext Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'memberRepository' defined in com.example.forq.MemberRepository defined in @EnableJpaRepositories declared on JpaRepositoriesRegistrar.EnableJpaRepositoriesConfiguration: Invocation of init method failed; nested exception is java.lang.IllegalArgumentException: Count query validation failed for method public abstract org.springframework.data.domain.Page com.example.forq.MemberRepository.findFetchJoinTeam(org.springframework.data.domain.Pageable)! paging에서 count 부분이 문제인것 같은데 entitygraph로 하면 잘 돼서 제가 뭔가를 놓친건지 궁금합니다 public interface MemberRepository extends JpaRepository<Member, Long> { @Override @EntityGraph(attributePaths = {"team"}) Page<Member> findAll(Pageable pageable);} 2. where 등으로 필터링을 하지 않을떄는 countQuery를 분리해서 최적화를 하면된다고 하셨는데 만약 select m from Member m join m.team t where t.name=:name ”같이 조인 대상에 필터링을 하는 경우에는 어떻게 최적화를 할 수 있는지 궁금합니다. 감사합니다!
-
미해결스프링 데이터 JPA
update 시 alter table account add column에서 그 뒤로 진행되지 않습니다.
JPA 프로그래밍 1. 프로젝트 세팅 강의를 따라하던 중 제 코드는 진행되지 않아서 문의 드립니다. database는 mySQL을 사용하였고, application.properties에서 ddl-auto를 update로 변경 후 실행하니 console에서 Hibernate: alter table account add column email varchar(255) 에서 아무 일도 일어나지 않습니다. 서버가 꺼지지도 않고 에러없이 JpaRunner 내의 run 함수에 접근을 하지 못하는 상태로 보입니다. 또한, 테이블 구조에는 변화가 없습니다. 이 문제를 어떻게 해야 해결할 수 있을까요? 제 application.properties입니다. 제 pom.xml 코드입니다. 마지막으로 코드 실행 시 나타나는 콘솔창입니다.
-
해결됨실전! 스프링 데이터 JPA
즐겁게 듣겠습니다~~~
어느덧 여기까지 왔어요 ㅎㅎ 이번 강의도 즐겁게 듣겠습니다. 항상 잘 듣고있어요
-
미해결실전! 스프링 부트와 JPA 활용1 - 웹 애플리케이션 개발
주문내역 검색 form 관련해서 질문입니다...
안녕하세요 강의 정말 재미있게 스프링핵심 원리, JPA 잘 듣고 있습니다. 주문 목록 검색 form 태그에 action 속성이 없는데 submit을 할경우 어떤식으로 작동하는지 이해가 잘 안가여 질문드립니다.
-
미해결실전! 스프링 부트와 JPA 활용1 - 웹 애플리케이션 개발
공부를 하면서..
spring 핵심 원리에서 배웠던 DI, interface를 이용해서 추상화하는 방식이 사용되고 있지않고. 그냥 private final ItemService itemService 이런식으로 진행하고 계시는데 jpa 강의라서 이렇게 간단하게 설계 하시는건가요?? 실무에서 프로젝트 사이즈가 커지다보면 자연스레 추상화하게 되나요?? 질문 자체가 이상했으면 죄송합니다..
-
미해결자바 ORM 표준 JPA 프로그래밍 - 기본편
스프링 커뮤니티
스프링 커뮤니티에 자주 올라오는 질문 이라고 하셨는데 따로 이용하시는 스프링 커뮤니티가 있나요?
-
해결됨자바 ORM 표준 JPA 프로그래밍 - 기본편
일반 조인과 fetch join 테스트를 해봤는데, 질문이 생겼습니다.
복습을 하면서 예제 코드를 이리저리 건드려 보고 있습니다. 그런데 문득 이런 생각이 들었습니다. fetch 조인 대신 그냥 join문을 써서 같은 효과를 낼 수 있지 않을까? 그래서 예제 코드를 약간 수정해서 아래 코드를 돌려봤습니다. Team teamA = new Team(); teamA.setName("팀A"); em.persist(teamA); Team teamB = new Team(); teamB.setName("팀B"); em.persist(teamB); Member member1 = new Member(); member1.setUsername("회원1"); member1.setAge(10); member1.changeTeam(teamA); em.persist(member1); Member member2 = new Member(); member2.setUsername("회원2"); member2.setAge(15); member2.changeTeam(teamA); em.persist(member2); Member member3 = new Member(); member3.setUsername("회원3"); member3.setAge(15); member3.changeTeam(teamB); em.persist(member3); em.flush(); em.clear(); String query = "select m,t From Member m join m.team t"; List<Object[]> resultList = em.createQuery(query).getResultList(); for (Object[] o : resultList) { System.out.println(Arrays.toString(o)); } 그러면 다음과 같은 결과를 볼 수 있습니다. (아 참고로, Member와 Team 클래스에 toString을 미리 설정했습니다. 연관관계만 뺀 나머지 필드는 모두 출력합니다) fetch join을 안 썼지만, 한 방 쿼리가 날렸고, 같은 효과를 내는 걸 확인 했습니다. 이렇게 일반 join을 쓰면 되는데 어떤 차이 때문에 fetch join을 써야 되는 건가요? 아니면 제가 뭔가 놓친 게 있는 걸까요?
-
미해결자바 ORM 표준 JPA 프로그래밍 - 기본편
왜 final 을 사용하면 안될까요!?
@Entity에는 final 클래스를 필드에도 사용하지 말라고 하셨는데 이유가 뭔지 궁금합니다.
-
미해결자바 ORM 표준 JPA 프로그래밍 - 기본편
다대일 양방향 질문입니다.
안녕하세요. 다대일 양방향 관계에 대해 질문 드립니다. Member 엔티티와 Team 엔티티가 다대일 양방향 맵핑 되어있고, package hellojpa; import javax.persistence.*; import java.util.ArrayList; import java.util.List; @Entity public class Member { @Id @GeneratedValue @Column(name= "MEMBER_ID") private Long id; private String name; private int age; @OneToMany(mappedBy = "member") private List<Order> orders = new ArrayList<Order>(); @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "TEAM_ID") private Team team; public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public void setTeam(Team team) { this.team = team; team.getMembers().add(this); } } package hellojpa; import javax.persistence.*; import java.util.ArrayList; import java.util.List; @Entity public class Team { @Id @GeneratedValue @Column(name = "TEAM_ID") private Long id; private String name; @OneToMany(mappedBy = "team",fetch = FetchType.LAZY) 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 List<Member> getMembers() { return members; } public void setName(String name) { this.name = name; } } 팀에서 getMembers 메소드를 통하여 해당 팀에 소속된 멤버들을 조회할 때 public class hellojpa { public static void main(String[] args) { EntityManagerFactory emf = Persistence.createEntityManagerFactory("hello"); EntityManager em = emf.createEntityManager(); EntityTransaction transaction = em.getTransaction(); transaction.begin(); try { Member member =new Member(); member.setName("member1"); member.setAge(20); Team team = new Team(); team.setName("team a"); em.persist(team); member.setTeam(team); em.persist(member); Member member2 = new Member(); member2.setName("member222"); member2.setTeam(team); em.persist(member2); em.flush(); em.clear(); List<Member> memberList = em.find(Team.class, team.getId()).getMembers(); for (Member member1 : memberList) { System.out.println(member1.getName()); } } catch (Exception e) { transaction.rollback(); } finally { em.close(); } emf.close(); } } 저는 select member0_.MEMBER_ID members0_.TEAM_ID members0_.age members0_.name from Member members0_ where members0_.TEAM_ID=? 이러한 쿼리가 생성될 것으로 예상했습니다. 하지만 실제 쿼리가 나간것을 확인해보니 select members0_.TEAM_ID as team_id4_0_0_, members0_.MEMBER_ID as member_i1_0_0_, members0_.MEMBER_ID as member_i1_0_1_, members0_.age as age2_0_1_, members0_.name as name3_0_1_, members0_.TEAM_ID as team_id4_0_1_ from Member members0_ where members0_.TEAM_ID=? select문에서 특정 컬럼들이 중복되어 표시되는데(bold표시), 혹시 이렇게 표시되는게 정상적인 것인지 혹은 맵핑 과정에서 실수가 있었던지 궁금하여 질문 드립니다!