월 16,940원
5개월 할부 시다른 수강생들이 자주 물어보는 질문이 궁금하신가요?
- 해결됨자바 ORM 표준 JPA 프로그래밍 - 기본편
중요한건 아니지만 설계 툴에 관해
안녕하세요. 중요한 질문은 아니지만테이블 설계와 엔티티 설계 할때 쓰시는 툴이 따로 있으신가 해서 질문드립니다.바쁘실텐데 감사합니다.
- 해결됨자바 ORM 표준 JPA 프로그래밍 - 기본편
스칼라 타입 프로젝션에서 이해가 안가는게 한가지 있습니다!
안녕하세요 스칼라 타입에서 질문이 있습니다!!!처음에 엔티티, 임베디드 타입, 스칼라 프로젝션을 다 같이 설명하실때 작성하셨던em.createQuery("select m.username, m.age from Member m")이 코드에서 실행하셨을때 스칼라 타입이 딱히 문제 없이 실행된 것 같은데 이건 조회를 하는 코드가 아닌가요....?다른 엔티티나 임베디드 타입은 그냥 저런 식으로 작성해서 조회가 된다고 하셨고 실행하셨을 때, 문제가 없는 것처럼 말씀을 하셨고스칼라 타입도 처음에 저렇게 실행을 하셨을 때, 결과 창이 비슷하게 나와서 저는 저게 조회하는 코드인 줄 알았는데 뒤에 바로 고민거리가 생긴다고 하시고 DTO을 생성한 뒤, new operation을 사용해서 코드를 작성하셔서 이렇게 조회를 해야된다고 하셨는데Q1. 그럼 제가 위에서 적은 조회하는 코드라고 생각했던 것은 왜 크게 오류가 안나고 실행이 된건가요....?Q2. 그리고 MemberDTO자리에 그냥 Member 엔티티로 대신 사용해도 문제 없이 실행이 되던데 DTO를 사용하는 이유는 중요 역할을 하는 엔티티를 반환하는 것이 설계상 안 좋아서 DTO를 따로 만드신 건가요???
- 미해결자바 ORM 표준 JPA 프로그래밍 - 기본편
강의를 쭉 듣다가 생긴 기본적인 질문입니다.
안녕하세요 다름이 아니라 강의들을 쭉 듣다보니앞에 @Enumerated 어노테이션을 설명하실때도EnumType.ORDINAL이 순서를 DB에 저장하는 것이라 실무에서 쓰지 말라고 하셨고이번에 JPQL에서도 파라미터 바인딩에서 위치 기준으로 바인딩하는건 쓰지말라고 하셨는데(이것도 순서를 기준으로 하는 것이니까 그런 것이겠죠??)Q. 실무에서 Spring이나 JPA뿐만이 아니라 다른 기술들을 쓰더라도 웬만한 상황들에 대해서 순서를 기준으로 데이터를 저장하거나 조회한다거나 이런 코드들은 데이터의 변화에 따라서 순서가 바뀔 수 있으므로 안쓰는 것이 좋은 가요?!
- 미해결자바 ORM 표준 JPA 프로그래밍 - 기본편
강의 실습 세팅하는데 오류 문제 어떻게 방법이 없을까요?
김영한님 좋은 강의 감사합니다. 다름이 아니라 제가 열심히 교육 드는데,초보자라 아직 모르게 좀 많습니다. 특히 실습환경 구축 시 오류가 뜨는 경우가 제법 있는데,아무리 검토하고 복붙을 활용해도 안되는 케이스가 있던데, 이게 노트북OS마다 다르겠지만, 적어도 실습할 수 있는 환경파일이나 최근에 촬영한 실습환경 구축 영상이라도 번외로 제공해주시면 오류 문제들이 최소화될 것 같습니다. 감사합니다 :)
- 미해결자바 ORM 표준 JPA 프로그래밍 - 기본편
다대일 양방향에 대한 정리와 질문
[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예)[질문 내용]아래는 제가 강의를 듣고 직접 변형 코드를 작성하면서 정리한 내용입니다.강의 중 member - team의 관계가 comment - team 으로 변경 되었다고 생각하시면 되겠습니다.제일 아래에 제 질문이 있습니다. 요약하자면, findByXXX 등으로 다대일 단방향 관계에서도 원활하게 데이터를 가져올 수 있는 것 같은데, 굳이 양방향을 사용하는 이유는 객체 지향적으로 코드를 짜기 위함인지, SQL 등에서 이점이 있는 지에 대해 궁금합니다.양방향 연관관계가 필요한가?댓글 같은 경우는 commentRepository에서 findByWriter로 가져오는 게 효율적인가? 아니면 Post 엔티티에서 comments에 대한 List 연관관계를 설정하고 가져오는 게 효율적인가?편한 건 post.getComments 로 가져오나, commentsService.findByWriter(Post post) 를 호출시켜서 가져오나 비슷한 것 같다.그런데 전자로 할 땐 account와 post 에만 select 문이 나가고, 후자로 할 땐 comments에 대한 select 문이 추가로 나간다.좋아요같은 경우는 자주 조회되니 post.getComments를 해두는 게 좋은건가?아래와 같은 연관관계 편의 메소드는 왜 필요할까?public void setPost(Post post) { this.post = post; post.getComments().add(this); } 어차피 em.persist(comment)에서 외래 키 값을 comment의 post에서 꺼내서 넣으면서 DB에 반영이 되며, JPA에서 실제 Post의 데이터를 사용하는 시점에 쿼리를 날린다. (지연로딩) 그래서 값을 세팅해주지 않아도 값이 출력이 된다.그러나 객체지향적으로 생각해보면 양쪽 다 값을 입력하는 것이 맞다.또한 post.getComments().add(this); 를 넣어주지 않으면 2군데서 문제가 생긴다.em.flush와 em.clear를 하지 않는 상황flush와 clear를 하면 1차 캐시에 아무것도 없으므로 DB에서 다시 조회해온다. 그래서 JPA가 FK가 있다는 것도 알고, 매커니즘이 동작한다.em.find해서 post을 가져올 때, 해당 post은 영속 컨텍스트의 1차 캐시에 있다. 위에 코드에서 세팅된 값 그대로 메모리에 올라가 있다.comments 컬렉션에 값이 있을까? 없다. 순수한 객체 상태이다.테스트 케이스 작성테스트 케이스를 작성할 때는 JPA 없이도 동작하도록 순수한 자바 단위로 테스트를 작성한다. 이때, 에러가 발생한다.양방향 연관관계 주의사항순수 객체 상태를 고려해서 항상 양쪽에 값을 설정하자.JPA에서의 설계는, 단방향 매핑만으로도 이미 연관관계 매핑은 완료테이블과 객체를 매핑한다는 관점에서만 보면, 단방향만으로도 설계가 완료된다.양방향 매핑은 반대방향으로 조회(객체 그래프 탐색) 기능이 추가된 것 뿐객체 입장에서는 양방향으로 설계해서 좋을 게 없다. 연관관계 편의 메서드 등 고민거리만 많아진다.그러나 실무에선, JPQL에서 역방향으로 탐색할 일이 많다. 그때 양방향으로 하면 된다.단방향 매핑을 잘하고 양방향은 필요할 때 추가해도 됨. (테이블에 영향을 주지 않음. 그냥 반대방향에서 컬렉션만 추가된 것.)즉, 설계할 때는 단방향 매핑만으로만 설계하고, 개발에 들어가서 양방향을 고민해도 늦지 않다. 객체 입장에서는 양방향 매핑에 대한 이득이 없다. 필요하다면 연관관계 편의 메서드로 양방향을 설정해주자.질문JPQL에서 역방향으로 탐색할 일이 많을 때 양방향으로 설정해야 하는 이유는 뭐지?코드를 객체지향적으로 짜기 위함인가, 아니면 SQL 쿼리에서 이점을 얻을 수 있는 건가?만약 둘 중 하나를 선택한다면, 나머지 하나는 없어도 되는 건가?양방향 연관관계 설정하고 post.comments로 JpaRepository의 findByWriter 역할을 대체한다면, findByWriter는 없어도 되는건가?영속 컨텍스트 1차 캐시에 없는 상태에서 post.getComments()로 가져올 때, Comment 에 대한 SQL에 select 문이 나가지 않는 이유는? 영속 컨텍스트 1차 캐시에 없는 상태에서 post.getComments()로 가져올 때, Comment 에 대한 SQL에 select 문이 나가지 않는 이유는?// Comment Select문 실행됨. @Transactional(readOnly = true) public List<Comment> findByPost(Long postId) { Post post = postService.findById(postId); return commentRepository.findByPost(post); } // 연관관계 편의 메소드를 사용한 코드 // Comment Select문 실행되지 않음. 값은 정상적으로 출력됨. @Transactional(readOnly = true) public List<Comment> findByPostObj(Long postId) { Post post = postService.findById(postId); List<Comment> commentList = post.getCommentList(); log.info("post.getCommentList = {}", commentList); return commentList; }
- 해결됨자바 ORM 표준 JPA 프로그래밍 - 기본편
em.remove() 메소드 관련 질문 드립니다.
em.remove() 메소드를 실행했을 때, 영속 컨텍스트 내부에 등록되어 있는 캐시가 삭제되는 건가요?제가 이해한게 맞는지 모르겠습니다.1) em.find()를 실행해서 엔티티가 영속 컨텍스트 내부 캐시에 등록되어 있지 않을 경우, DB를 조회해서 객체를 영속 컨텍스트에 저장2) em.remove()를 실행했을 때, 캐시에 등록되어 있던 엔티티가 삭제하고 delete 쿼리문을 쓰기 지연 SQL 저장소에 저장3) 커밋이 실행되면 delete 쿼리문을 실행답변 부탁드리겠습니다!
- 미해결자바 ORM 표준 JPA 프로그래밍 - 기본편
소스코드 깃헙 주소있나요?
자바 ORM 표준 JPA 프로그래밍 - 기본편소스코드 깃헙 주소있습니까?
- 미해결자바 ORM 표준 JPA 프로그래밍 - 기본편
일대다 단방향은 무조건 피해야 하나요?
일대다 단방향 매핑에서 다음의 두가지 단점이 있다고 말씀해 주셨습니다.추가적인 update 쿼리의 실행엔티티가 관리하는 외래 키가 다른 테이블에 있음그런데 일대다 단방향 매핑을 맺을 때 updatable=false와 nullable=false를 추가하면 update 쿼리 없이 한 번에 insert 쿼리만 나가는 것을 확인했습니다.@OneToMany(cascade = {CascadeType.PERSIST, CascadeType.REMOVE}) @JoinColumn(name = "parent_id", nullable = false, updatable = false) private List<Child> children = new ArrayList<>();물론 부모 자식간 관계가 변하지 않고 라이프사이클이 완전 동일한 경우에만 활용할 수 있을 듯 합니다.그럼 update 쿼리가 추가적으로 나가는 것은 해결한 셈인데 이런 경우에도 엔티티가 관리하는 외래키가 다른 테이블에 있다는 단점에 의해 다대일 양방향을 맺어줘야 할까요? 복잡한 실무에서는 그 패러다임 불일치가 많은 영향을 주나요?
- 미해결자바 ORM 표준 JPA 프로그래밍 - 기본편
jpql
1. flush2. 디비로 쿼리날림3. 쿼리결과가 영속성컨텍스트에 있으면 버리고 없으면 저장 . update : 업데이트 시킨 엔티티를 반환하진 않기때문에. 그 숫자만 반환하기때문에 3번과정을 거치진 않는다 1+2과정만 거친다insert : 쿼리dsl같은경우는 insert대신에 persist를 사용한다. select : 1,2,3과정을 거친다제가 설명한게 맞나요?
- 미해결자바 ORM 표준 JPA 프로그래밍 - 기본편
기존 DB의 테이블과 jpa로 만들어진 테이블과 관계 맺기
[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예/아니오)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오)[질문 내용]이미 실무에서 사용중인 데이터베이스가 있습니다. 이 DB 안에는 기 생성된 테이블들이 있구요. JPA를 활용해 기존 DB에 접근해 필요한 테이블들을 추가하고 엔티티 매핑하는 작업들은 잘 되었는데요. 문제는 기존 DB의 "User" 테이블과 제가 새로 만든 테이블의 관계를 맺어주는 것이 가능한건가 해서요. [tb_user] <- 기존에 존재하던 테이블 (아래는 스키마)user_id : String : "S00001"name : String : "홍길동"age : int : 30[tb_user_history] <- 새로 등록한 테이블@Entity @Data @Table(name="tb_user_history") public class UserHistory { @Id @GeneratedValue(strategy = GenerationType.AUTO) @Column(name="user_history_id") private Long id; //연관 관계를 맺어주는게 가능한가요?????? private String user_id; }제 프로그램상에서 생성하고 관리하는 테이블이라면 @ManyToOne, @JoinColumn을 이용해서 조인과 외래키 생성 작업을 해줄수있는데 지금과 같은 경우에서는 어떤식으로 가능할까요?
- 미해결자바 ORM 표준 JPA 프로그래밍 - 기본편
임베디드 타입은 비교 지원하지 않는다는데 왜 비교가 되는걸까요
책 399페이지를 보면 비교를 지원하지 않는다고 되어있는데 제코드에서는 비교연산이 되는 것 같아요.. 왜그러는걸까요 제가 잘못이해한건가요?
- 해결됨자바 ORM 표준 JPA 프로그래밍 - 기본편
'스프링에서 엔티티 매니저와 영속성 컨텍스트가 N:1'의 의미 질문 드립니다.
[질문 템플릿]1. 강의 내용과 관련된 질문인가요? 예2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? 비슷한 질문 있지만 해결 되지 않음3. 질문 잘하기 메뉴얼을 읽어보셨나요? 예[질문 내용]'스프링에서 엔티티 매니저와 영속성 컨텍스트가 N:1'의 의미 질문 드립니다.강의 4분 1초쯤 스프링에서는 엔티티 매니저와 영속성 컨텍스트가 N:1 이라는 장표가 있는데 아래와 같이 이해했습니다.N개의 EntityManager 객체들은 동일한 PersistenceContext 객체를 참조하고 있음 (싱글톤)위 내용을 확인 해보고자 본 강의의 소스파일(jpashop-v20210728)을 인텔리제이에서 디버그 실행한 상태에서 다수의 HTTP 요청을 보내서, HTTP 요청마다 생성된 다수의 EntityManager 객체가 하나의 PersistenceContext 객체를 참조하고 있는지 확인했습니다. 확인 결과 EntityManager 객체마다 각각 다른 PersistenceContext 객체를 참조하고 있었습니다. 5번의 HTTP 요청을 보내서 5개의 엔티티매니저 객체와 영속성 컨텍스트 객체가 생성됐습니다. 위 내용만 본다면, 스프링부트 프로젝트인데 J2SE 환경과 마찬가지로 엔티티 매니저와 영속성 컨텍스트가 1:1로 생성되는것으로 보여서, 제가 위 장표를 잘못 이해한것 같아 질문 드립니다.감사합니다~
- 미해결자바 ORM 표준 JPA 프로그래밍 - 기본편
jpql
select t from Team t where t IN (select m.team from Member m where m.age >= 20)select t from Team t where t IN (select t2 From Team t2 join t2.members m2 where m2.age >= 20)-> 결과 같게 나오는데 같은 쿼리인게 맞을까요...?-> 근데 이게 서브쿼리의 결과는 다른데 in을썼기때문에 같은결과가 나오는거일까요?
- 미해결자바 ORM 표준 JPA 프로그래밍 - 기본편
join fetch
n + 1 문제를 해결하기 위해 join fetch를 써야 하는걸로 배웠는데 inner join으로 해석이 되는 join fetch를 혹시 한 쿼리 안에서 여러번 쓸때 어떨때는 inner join으로 해석하고 어떨때는 outer join으로 해석하게 설정을 할 수 있나요? (inner join과 outer join을 쓰고 싶은데 join fetch를 여러번 쓸경우 inner join으로만 해석이 됩니다.)
- 해결됨자바 ORM 표준 JPA 프로그래밍 - 기본편
jpql의 객체지향 쿼리라는 말이 궁금합니다
기본적으로 find를 통한 DB조회를 하여도 각 테이블의 컬럼에 있는 값을 가져오는것인데jpql을 사용해도 똑같이 DB의 테이블내 컬럼값을 가져오는것이 아닌지 의문입니다.또한 jpql이 객체지향 쿼리라고 불리는것은 테이블을 기반으로 DB조회를 하는게 아닌 객체를 기반으로 DB조회를 하기때문인가요?만약 맞다면 모든 DB테이블이 객체로 이루어져 있어야하기때문에 JPQL 단독사용이 불가능한지도 궁금합니다 감사합니다
- 미해결자바 ORM 표준 JPA 프로그래밍 - 기본편
INSERT 문이 동작을 안합니다.
[질문 내용]안녕하세요.강의 10:15초에서부터 tx.begin으로 db 트랜젝션을 생성하여 insert 쿼리를 전달하는데 영한님처럼 terminal 창에 에러도 안나오고, h2 db에 insert도 되지 않습니다.JPA Main class를 실행시켰습니다.System.out.println("1111"); 을 실행시켜도 터미널에 나오지 않습니다......termianl창 출력 내용 :"C:\Program Files\Java\jdk1.8.0_291\bin\java.exe" "-Process finished with exit code 0
- 해결됨자바 ORM 표준 JPA 프로그래밍 - 기본편
39분 때 em.clear()에 관해서 질문이 있습니다.
강의에서 39분 쯤에 em.detach(), em.close()는 왜 프록시가 초기화가 안되는지 이해했습니다.근데 em.clear()는 단순히 영속성 컨텍스트를 비우는 것으로 아는데원래 프록시가 영속성 컨텍스트에 초기화 요청을 하고 없으면 DB에 조회를 해서 실제 Entity를 target으로 가져오는 것으로 이해를 했는데 em.clear()로 비워져있다고 refMember.getUsername()이 왜 안되는 것인지 이해가 가질 않았습니다. 그래서 생각해본 결과 질문이 있습니다.Q. 혹시 프록시 초기화를 요청하는 과정이 em.getReference()로 조회를 하면 그때 이미 프록시 객체가 진짜 객체 대신에 영속성 컨텍스트에 보관되고 뒤에 refMember.getUsername()이나 기타 다른 초기화 요청이 올 때 영속성 컨텍스트에서 DB로 조회해서 실제 객체를 프록시 내부로 들이는 것인가요...?
- 미해결자바 ORM 표준 JPA 프로그래밍 - 기본편
임베디드 컬렉션 값 조회 jpql시 오류
public void 임베디드값조회(){ List list = em.createQuery("select m.addressList from Member m").getResultList(); for (Object o : list) { System.out.println(o); } }다음과 같은 오류가 뜹니다 not an entity [select m.addressList from jpaStudy.ex.entity.Member m]근데 m.addressList가 엔티티는 당연히 아니잖아요?왜 저 문장에 오류가 있는건가요? addresslist는 강의에 나온 address의 list버전입니다.
- 미해결자바 ORM 표준 JPA 프로그래밍 - 기본편
값 타입 컬렉션의 제약사항
Address address1 = new Address(null, "2"); Address address2 = new Address("3", "4"); Address address3 = new Address("3", "4"); List<Address> addressList = new ArrayList<>(); addressList.add(address1); addressList.add(address2); addressList.add(address3); Member member = new Member(); member.setAddressList(null); em.persist(member); //변경 em.flush(); address1 = new Address("213", "!23"); addressList.remove(0); addressList.add(address1);컬럼에 null을 입력할 수 없다는데.. 입력해도 테스트를 통과해요 제가 어떤부분을 잘못알고있는건가요?같은값을 중복해서 저장할 수 없다는데 2번째 3번째 줄을 보면 잘 저장하고 있지 않나요..?
- 미해결자바 ORM 표준 JPA 프로그래밍 - 기본편
generatedvalue선택하고 setter하기
generatedvalue로 id값이 생성됐는데 전 그걸까먹고 id값을 setting해줬어요그랬더니 detached entity passed to perist 라는 오류가떴어요준영속엔티티를 영속화시키려고해서 발생하는오류잖아요?왜 이런 오류가뜨는걸까요? id생성전략은 sequence예요sequence는 다음과 같이 동작해요<<persist 를 호출하면 sequence 를 가져옵니다.가져온 Sequence 를 id 에 할당하고 (영속성 상태), transaction 이 commit 될 때, insert 쿼리를 날립니다.>>근데 이러면 제가 set을 해도 새로운 id에 덮어씌여져야하는거아닌가요?