25%
66,000원
다른 수강생들이 자주 물어보는 질문이 궁금하신가요?
- 미해결실전! 스프링 데이터 JPA
@Transcational을 서비스계층에 하는 이유는 무엇인가요?
레포지토리 계층에 @Transactional가 이미 되어 있는데 Service단에 @Transactional을 붙이는 이유가 무엇인가요?
- 미해결실전! 스프링 데이터 JPA
낙관적인 락
안녕하세요 영한님! 간단하게 비관적인 락과 낙관적인 락 예시에 대해 궁금한게 있습니다. 비관적인 락 같은 경우에는 동시에 많은 요청이 들어와서 모두 카운트해서 올려야하는 조회수 같은 곳에 사용한다고 구글링을 해보니 나오는데 낙관적인 락을 사용하는 예시는 찾을 수 없어서 혹시 실무에서 낙관적인 락을 사용하는 사례는 어떤게 있을 까요?
- 미해결실전! 스프링 데이터 JPA
MemberRepositoryTest 질문
MemberRepositoryTest에서 실행을 하면 create 쿼리는 뜨는데 insert 쿼리는 안뜹니다. h2데이터 베이스에 들어가서 확인해 봤는데 "memberA" 가 안들어가네요 설정 문제인가요??ㅜ
- 미해결실전! 스프링 데이터 JPA
업데이트 질문입니다.
안녕하세요 마지막부분에 basicCRUD 테스트 함수에서요 member1을 save하고 findById로 findMember1을 가져온 뒤 findMember1.setUsername("member!!!") 로 업데이트하고 있는데요 변경감지 기능을 사용할 때, 트랜잭션 안에서 엔티티를 조회하고, 변경할 값을 set 해주면 트랜잭션 커밋 시점에 변경 감지가 동작해서 update 쿼리가 나간다고 배웠습니다. 그래서 예상하기로 update member set username='member!!!!!' where member_id = 1; 이렇게 쿼리가 나갈거라고 생각했는데 update member set age=0, team_id = NULL, username='member!!!!!' where member_id = 1; 이렇게 쿼리가 나가는 걸로 보여서요. 해당하는 컬럼만 업데이트 되는게 아니라 전체 칼럼이 업데이트 되는건가요? 전체 칼럼 업데이트 merge, 해당 칼럼 업데이트는 변경감지. 이렇게 배운거 같아서요
- 미해결실전! 스프링 데이터 JPA
spring jpa 실습시 질문이 있습니다.
h2 를 사용해서 jpa 테스트코드를 돌려보고있는데... 테이블 생성 후 데이터 insert 하고, 로그까지 찍었을때는 정상적으로 테스트코드가 잘 동작햇습니다. 그런데 실제로 h2 db에 접속해서봤더니.. 해당 테이블이 다 사라지고 없는데... 어떤 설정을 해야하나요? spring: datasource: # url: jdbc:h2:tcp://localhost/~/imageTest username: image password: driver-class-name: org.h2.Driver jpa: hibernate: ddl-auto: create properties: hibernate: show_sql: true format_sql: truelogging.level: org.hibernate.SQL: debug
- 미해결실전! 스프링 데이터 JPA
안녕하세요 개인 프로젝트중 궁금한게 생겨서 질문드립니다.
안녕하세요 선생님 스프링부트를 이용한 프로젝트를 진행중에 궁금한 것이 생겨서 꼭 알고 싶은 마음에 질문하게 되었습니다. 프로젝트 구성은 이렇습니다. Entity는 User, Board, Comment를 만들었고, Spring Data Jpa를 활용하여 각각의 repository인 UserRepository, BoardRepository, CommentRepository도 만들었고, service부분인 CommentServiceImpl을 구성하는 중에 문제가 발생하였습니다. @Service public class CommentServiceImpl implements CommentService{ ... @Override public Long create(User user, Long board_id, String content) { Board board = boardRepository.findById(board_id).get(); //user.getClass() = class com.graduation.parrot.domain.User //proxy가 아님을 확인 System.out.println("user.getClass() = " + user.getClass()); //user.getBoards() = [Board(id=2, title=title1, content=at), ... //정상실행 System.out.println("user.getBoards() = " + user.getBoards()); //LazyInitializationException 발생 System.out.println("user.getComments() = " + user.getComments()); return commentRepository.save(new Comment(content, user, board)).getId(); } 에러메시지 : org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: com.graduation.parrot.domain.User.comments, could not initialize proxy - no Session 원래는 System.out.print...이 부분이 없었지만 이해를 돕기위하여 추가하였습니다. (return 부분의 new Comment를 생성할때 생성자에서 user.getComments()가 실행됩니다.) 테이블의 연관관계 매핑은 [user : board - 1대다], [user : comment - 1대다], [board : comment - 1대다] 이렇게 구성하였습니다. 제가 생각할때 user.getBoards()와 user.getComments()가 구조상 차이가 없어보이는데 스프링은 그렇게 생각하지 않는지 user.getComments()를 실행할 때만 에러를 발생시킵니다.. 문제상황 자체를 해결하는 방법은 찾았으나(user를 바로 사용하지 않고 userRepository.findById() 이용) 왜 user.getComments()만 문제가 발생하는지 꼭 알고 싶습니다. +@Transactional를 달아도 에러가 발생합니다 아래는 Entity들의 자바코드입니다. User @Entity @Getter @NoArgsConstructor(access = AccessLevel.PROTECTED) @ToString(of = {"id", "name", "login_id", "password"}) public class User extends BaseTimeEntity{ @Id @GeneratedValue @Column(name = "user_id") private Long id; @Column(nullable = false, length = 100, unique = true) private String login_id; @JsonIgnore @Column(nullable = false, length = 100) private String password; @Column(length = 15, unique = true) private String name; @Column(length = 100) private String email; @Enumerated(EnumType.STRING) private Role role = Role.ROLE_USER; @OneToMany(mappedBy = "user", cascade = CascadeType.ALL) private List<Board> boards = new ArrayList<>(); @OneToMany(mappedBy = "user", cascade = CascadeType.ALL) private List<Comment> comments = new ArrayList<>(); @Builder public User(String login_id, String password, String name, String email) { this.login_id = login_id; this.password = password; this.name = name; this.email = email; } } Board @Entity @NoArgsConstructor(access = AccessLevel.PROTECTED) @Getter @ToString(of = {"id", "title", "content"}) public class Board extends BaseTimeEntity{ @Id @GeneratedValue @Column(name = "board_id") private Long id; @Column(nullable = false, length = 30) private String title; @Column(length = 1000) private String content; private String author; @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "user_id", updatable = false) private User user; @OneToMany(mappedBy = "board", cascade = CascadeType.ALL) private List<Comment> comments = new ArrayList<>(); @Builder public Board(String title, String content, User user) { this.title = title; this.content = content; this.author = user.getName(); setUser(user); } public void setUser(User user) { this.user = user; user.getBoards().add(this); } Comment @Entity @NoArgsConstructor(access = AccessLevel.PROTECTED) @Getter @ToString(of = {"id", "content"}) public class Comment extends BaseTimeEntity{ @Id @GeneratedValue @Column(name = "comment_id") private Long id; @Column(nullable = false) private String content; private String author; @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "user_id") private User user; @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "board_id") private Board board; @Builder public Comment(String content, User user, Board board) { this.content = content; this.author = user.getName(); setUser(user); setBoard(board); this.board = board; } public void setUser(User user) { this.user = user; user.getComments().add(this); //System.out.print를 지우고 정상실행시 이 부분에서 지연로딩 에러가 발생합니다. } private void setBoard(Board board) { this.board = board; board.getComments().add(this); } }
- 해결됨실전! 스프링 데이터 JPA
Optional 적용 문제
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요.1. 강의 내용과 관련된 질문을 남겨주세요.2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요.(자주 하는 질문 링크: https://bit.ly/3fX6ygx)3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요.(질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG)질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요.=========================================[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예/아니오)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오)[질문 내용]여기에 질문 내용을 남겨주세요. 회원 이메일을 사용하여 MemberRepository에서 회원 정보를 조회하는 메서드를 구현해 보았습니다. 해당 이메일의 회원이 DB에 존재하지 않을경우를 고려하여 다음과 같이 Optional로 감싸주었습니다. Transactional(readOnly = true) public interface MemberRepository extends JpaRepository<Member, Long> { Optional<Member> findByEmail(String email); ... } 이 경우 Service 단에서 해당 메서드를 사용할 경우 변수 타입을 Optional<Member>로 선언해 줘야 했습니다. @Transactional public void followFriend(FollowFriendRequest request) { Member requester = getMember(request.getRequesterEmail()); Optional<Member> receiver = memberRepository.findByEmail(request.getReceiverEmail()); log.info("requester: '{}', receiver: '{}'", requester, receiver); if (receiver == null) { throw new MemberEmailNotFound(); } if (requester.hasFriend(receiver) || relationRepository.existsByOwnerEmailAndFriendEmail(request.getRequesterEmail(), request.getReceiverEmail())) { throw new EmailDuplicatedException(request.getReceiverEmail()); } relationRepository.save(new Relation(requester, receiver)); } 이러면 위 코드 마지막 줄의 Relation 생성자 또한 Optional을 포함한 생성자를 추가로 만들어 줘야 하고 이렇게 되면 Relation 엔티티의 receiver 필드값에도 Optional을 씌워줘야 하는 문제가 발생했습니다. 이 경우 Optional을 어떻게 사용하는게 옳은건지 궁금합니다.
- 미해결실전! 스프링 데이터 JPA
데이터베이스 연결
제가 Data Jpa를 테스트 해보려고 하는데 Table "ARTICLE" not found 에러가 발생합니다 분명히 ddl-auto에 의해서 Article 테이블이 자동 생성되는데 왜 SQL 문법 에러가 나는가 싶어서 workbench에서 select문을 던져봤는데 실제로 Article 테이블이 존재하지 않는다고 합니다. 좀 더 찾아본 결과 workbench에서 구체적인 database가 선택되지 않아 발생한 문제 인 것 같습니다 workbench에서 select * from article; 은 에러가 나지만 select * from mydb.article; 이나 use mydb 이후 select * from article;은 문제 없이 작동합니다 이 경우 data jpa에서 나가는 쿼리문이 문제인 것 같은데 insert into (테이블 이름) 에서 테이블 이름 앞에 prefix를 넣는 방법이 따로 있을까요?
- 해결됨실전! 스프링 데이터 JPA
질문있습니다.
Auditing에서 @PreUpdate를 사용하면 자동으로 수정된 시간이 저장되는데요. 복습하다 궁금한점이 생겼습니다. 만약 회원의 마지막 접속 날짜를 얻어올려면 제가 생각하기에는 엔티티에 lastLogin 같은 LocalDateTime 타입의 필드를 추가해야 할것같은데요. 즉, 로그인할때마다 lastLogin에 LocalDateTime.now()을 이용하여 해당 테이블에 업데이트시키면 될것같은데 생각해보니 lastLogin을 업데이트 시키면 @PreUpdate의 필드도 업데이트 쿼리가 수행되면 현재 시간이 저장됩니다. 그럼 뭔가 마지막 접속 날짜를 얻기위해 새로운 필드(lastLogin)을 추가하지않고 @PreUpdate를 이용하여 마지막 로그인 시간을 가져올 방법이 있지 않을까해서 질문드립니다. 만약 @PreUpdate를 이용하여 마지막 로그인 시간을 가져오는 방법이 없다면 제가 위에서 예시로 든것처럼 마지막 로그인 시간을 저장할 필드를 추가해야하나요?
- 미해결실전! 스프링 데이터 JPA
@EntityListeners로 오딧항목을 업데이트 하려는데 다른 테이블도 같이 업데이트 됩니다.
[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예)[질문 내용]안녕하세요. 오딧항목 처리부분 구현해 보다가 이상하게 동작하는 부분이 있어서 문의드립니다. Car - Body < Part 구조가 있을 때, 즉 Car 는Body 와 1:1,Body 와 Part 는 1:n 관계가 있습니다. JPA에서는 모두 양방향 참조로 Car에서 Part 까지 접근 가능하고, 연관관계 주인은 Car -Body 에서는Body 가,Body < Part 에서는Part 가 가지도록 했습니다. 엔티티 저장을 편리하게 하기위해서 모든 OneToXXX 는 cascade 모드를 ALL 로 설정했습니다. 각 엔티티는 Audit 처리를 위해 Audit MappedSuperclass를 상속하고 이 클래스는 int 타입의 version 필드를 가지고 있습니다. 이 Audit 엔티티에 @EntityListeners 를 등록해서 Create, Update 시 버전을 올릴려고 AuditListener 을 구현하고 참조합니다. 오딧 테스트를 위해 @BeforeEach 애노테이션으로 데이터를 넣고 @Test 애노테이션으로 테스트를 수행했습니다. Car 를 리포지토리에서 가져와서 Body 를 통해 Part 를 가져왔고 Part 의 이름을 업데이트 했습니다. 기대하는 값은 Part 테이블의 version 필드가 1 이 되는 것인데, Part 테이블은 정상적으로 1 로 업데이트 됐지만 Car 테이블의 버전도 1 로 바뀌었습니다. 왜 이렇게 동작하는지 궁금합니다. 자세한 사항은 너무 길에서 별도 페이지에 작성하였습니다. 양해 부탁드립니다. JPA Test를 위한 @BeforeEach 와 트랜잭션 분리 감사합니다.
- 미해결실전! 스프링 데이터 JPA
[Error] Use @Param for query method parameters, or when on Java 8+ use the javac flag -parameters.
안녕하세요 영한님 spring data jpa 를 사용해서 사이드 프로젝트를 진행 중인데 발생하지 않던 에러가 발생하여 너무 이상해서 이렇게 질문을 드립니다. 처음 @Query 어노테이션을 사용하여 @Param을 따로 사용하지 않고 데이터를 바인딩 해주었습니다. (제가 알고 있기론 spring 4version 이상부터는 파라미터의 이름이 같을 시 생략이 가능하다고 알고있었습니다.) 그리고 실제로 @Param을 사용하지 않고도 잘 적용도 되었고 문제없이 실행되었지만 기능을 확장하는 과정에서 갑자기 ava.lang.IllegalStateException : For queries with named parameters you need to use provide names for method parameters. Use @Param for query method parameters, or when on Java 8+ use the javac flag -parameters. 이렇한 에러가 발생한 것이었습니다. 그래서 @Param 어노테이션을 사용해서 해결은 하였지만 정확히 왜 기존에는 잘 되었는지, 그리고 이제와서 에러가 발생한건지 원인을 찾고 싶었는데 아무리 검색해도 찾지를 못했습니다. 혹시 이에 대해 정보를 얻을 수 있을까요??? 감사합니다
- 미해결실전! 스프링 데이터 JPA
해당 영상에서 member엔티티의 id값 할당방식
@Id @GeneratedValue Member 엔티티의 id생성이 auto로 디폴트값인데, 영상 7분 10초에 멤버의 객체생성이 하나뿐인 테스트에서id값이 1이아닌 2로 뜨는지 궁금합니다.
- 미해결실전! 스프링 데이터 JPA
이후 과정에 대해 질문이 있습니다.
여기에 질문을 하는게 맞는지 모르겠지만 혹여나 저와 비슷한 고민을 하는 사람들도 있을까 싶어 여기에 남겨봅니다. 저는 이제 막 강사님의 스프링부트 기초, JPA 1,2 , 데이터 JPA 까지 다 듣게 되었습니다. 뭔가 배우면 그걸 바로 써먹고 싶어서 간단한 프로젝트를 해보려 했는데 생각보다 의도대로 흘러가지 않는다는걸 느꼈습니다.. 대부분 시작은 그렇겠지만 아직 덜 배웠다는 느낌이 매우 강합니다. 예를 들어 기본적인 글과 댓글을 남기는 게시판이야 어렵진 않은데 이미지 파일 등을 처리하는 과정이 제가 이전에 쓰던 장고와는 좀 많이 달라 약간 어려움이 있습니다. 좀 알아보니 강사님께서 강의하신 스프링MVC 강의에 해당 내용이 있는듯 한데 저같은 경우엔 우선 잘 모르더라도 남들이 쓴 코드를 보고 대충 적용해서 간단한 토이프로젝트를 완성하는게 좋을지 혹은 강사님의 스프링MVC 강의를 듣고 좀 더 완성도 있게 진행하는 방향이 좋을지 궁금합니다.
- 미해결실전! 스프링 데이터 JPA
repository는 entity당 개별로 생성해줘야 하나요?
[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예)[질문 내용]강의내용을 보면 Member와 Team 엔티티가 있고 JpaRepository를 상속받은 repository 또한 각각 만들어져 있습니다. 단순한 조회는 이미 정의되어있는 메소드로 가능하지만, 다른 테이블(엔티티)와 조인하는 경우에는 직접 정의해서 사용 가능하다는 내용의 강의였는데요 그럼 만약 4개 5개 복잡한 엔티티들과 연관된 쿼리들을 정의하고 싶다면 어느 repositroy에 정의를 해야할지 고민입니다. 여러 엔티티를 1개의 repository로 관리하고자 해도, 상속받을때 <>속에 특정 엔티티를 넣어줘야하는데, 그럼 어떤 엔티티를 넣어야할까요? 코딩에 정답은 없겠지만은 실무에서는 관례쩍으로 어떤식으로 구현을 하는지 궁금합니다.
- 미해결실전! 스프링 데이터 JPA
선생님 질문이 있습니다!
안녕하세요! 강의 재밌게 수강하고 있습니다! 실례가 안 된다면 혹시 선생님께서 말씀하시는 핵심 비즈니스 로직과 화면 혹은 API에 맞춘 로직의 차이점을 간단하게 설명해주실 수 있으실까요? 저는 화면에 출력하거나 API를 만드는 게 곧 핵심 비즈니스 로직이라고 생각했는데 제가 잘못 생각하고 있었던 거 같아 혹시 도움을 받을 수 있을까 하여 질문 남기게 됐습니다 ㅠ + Trade off는 어떤 의미로 이해하면 좋을까요? ㅠㅠ P.S 비전공자로 여러 강의를 들으면서 선생님 강의 만난 게 최고의 행복인 거 같습니다! 종종 PPL 하시는 JPA 책도 잘 읽고 있는데 언젠가 기회가 되면 선생님께 싸인 받고 싶습니다 ㅋㅋㅋ 존경합니다 선생님!
- 미해결실전! 스프링 데이터 JPA
File-project Structure 설정
안녕하세요 강의 잘 보고 있습니다. 4:30초 쯤에 하는 설정으로 인해서 멤버 변수 옆에 주황색 a 가 생겼는데 이것이 의미하는 것은 무엇인가요?
- 미해결실전! 스프링 데이터 JPA
entitygraph관련 궁금증
안녕하세요!! 만들어주신 로드맵을 열심히 공부하고 있는 학생입니다! @entityGraph와 관련하여 추가적인 궁금증이 있어 질문드립니다. 먼저 해당 내용에 대해 repository 내에서 findAll() 메소드를 상속받아, 여기에 fetch join을 부여해 주는 것으로 이해했는데요 혹시 이렇게 상속받으면 findAll 메소드 자체가 바로 fetch join을 진행하는것이 아닐까 해서요 예를 들어 A 위치에서는 member의 변수만을 필요로 하고, B 위치에서는 team까지 가져오려 하면 A에서는 LAZY로 유지되는 것이 좋고, B에서는 바로 fetch join하는 것이 나을 거라 생각하는데 위의 방식이면 둘 다 바로 fetch join을 진행할 것 같다고 생각하는데 이게 맞을까요?? 혹시 맞다면 어떤 식으로 고치는것이 더 최적화될지 궁금합니다.... --- 추가로 혹시 @entityGraph는 무조건 left outer join에서만 적용되는 것일까요??
- 미해결실전! 스프링 데이터 JPA
@Path variable로 Id를 받을 때 궁금증
강의를 듣다가 궁금한게 생겼는데요 Id 같은 PK의 경우에 좀 중요한 정보라고 생각을 합니다. 사용자 입장에서는 자동적으로 매겨진 pk인 id를 모르겠지만 이것을 사용자 측에서 저장하고 server와 주고 받는것이 맞는건지 궁금합니다. 공부를 하는 입장이라 실무에서는 어떤 방식으로 사용자 정보를 조회하도록 하는지가 너무 궁금합니다. ID정도는 넘겨줘도 상관이 없는건가요? 아니면 이러한 정보를 절대 전송하면 안되고 매번 session에서 꺼내야 하는건가요? cookie 에서 이 값을 저장해도 무방한가요? 무엇이 나은가요? ㅠㅠ cooki Id
- 해결됨실전! 스프링 데이터 JPA
Repository 구현체와 인터페이스
안녕하세요. 강의에서는 JpaRepository 구현체와 JpaRepository를 상속받은 인터페이스 Repository 두개를 만들어서 비교하는 형태로 강의를 하셨는데 1.영한님께서도 보통 두가지를 따로 만들어서 주로 인터페이스 Repository에서 처리할수 있는것들은 처리하고, 인터페이스만으로는 안되는것들은 구현체Repository에서 처리하시나요?? 2. 지금 강의를 들어보면 인터페이스Repository에서도 jpql쿼리문을 작성할수있기때문에 구현체Repository를 사용할일이 없어보이는데 인터페이스에서는 불가능한 예시 하나만 들어주실수있으실까요? 항상 감사합니다!
- 미해결실전! 스프링 데이터 JPA
21:30 질문
21:30 시간에 기본적으로 optional로 findById가 반환된다고 하셨는데요. orElseGet으로 하면 빈 Member를 넘겨주는게 좋을까요? 실무에서 어떤 방식으로 findById했는데 해당 정보가 없는경우 어떻게 처리해주는지 그것이 궁금합니다. orElseGet으로 하면 없다는것에 대한 기준(예를 들어 Member의 이름이 nothing 이거나, 다른방식이던)을 어떻게 해주는게 좋을지 고민입니다