묻고 답해요
138만명의 커뮤니티!! 함께 토론해봐요.
인프런 TOP Writers
-
미해결실전! 스프링 부트와 JPA 활용1 - 웹 애플리케이션 개발
테이블 아이디 설계 및 hidden 태그 관련 질문 드립니다.
항상 명강의 감사합니다. 강의를 들을때마다, 강사님에 노고가느껴지니, 매번 소름이 돋네요. ㅎㅎ 오늘도 강의 잘 듣고 있습니다. 2가지 질문을 드립니다. 1. 테이블 아이디 설계 저는 회원 테이블을 설계할때, 기본키를 '아이디' 로 설정했었습니다. 아이디가 유니크 하기 때문에 기본키로 잡았었는데, 강의에서는 엔티티에서 기본키를 따로 잡으시고(기본키는 자동으로 값을 셋팅) 진행을 하시던데 실무에서도 회원 테이블을 설계하신다면 '회원 아이디' 와는 별개로 기본키 필드를 설계하고 @GereratedValue 로 자동으로 값을 할당하도록 진행하시나요.? 2. hidden 태그(다소 부족한 질문일수도 있습니다.)강의 내 코드를 보면, 회원에 대한 아이디를 hidden 태그에 노출하는데, 이게 보안상에 문제가 될 여지는 없을 까요.? 물론 서버단에서 회원에 권한을 체크한다면 문제가 되지 않는다고는 생각하지만, 노출된다는게 꺼림칙해서요.....(단순히 제생각입니다.) 아니면 hidden 태그를 사용하지 않고, 구현하는 방법이 따로 있을까요.?
-
해결됨실전! 스프링 부트와 JPA 활용1 - 웹 애플리케이션 개발
엔티티에서 @GeneratedValue에 관한 질문입니다!
안녕하세요 항상 좋은 강의에 항상 감사하고 있습니다! 다름이 아니라 JPA를 통해서 디비를 생성하지 않고 이미 따로 MySQL로 만든 디비를 객체에 매핑만 하여 사용하려고 하는데요! 1. 보통 이렇게 하는게 일반적인가요? 2. 이미 pk로 순서대로 1, 2, 3 ... 을 맥인 상황에서 엔티티와 매핑하고 그 다음 jpa 를 통해 insert를 하게 되면 가장 마지막 id값을 읽고 그다음 자동으로 이어서 +1 을 하게 되주나요? 질문이 너무 두서가 없네요 ㅠㅠ 예를 들어 이미 기존 member라는 테이블에 (pk로 id 컬럼) 1 memberA 20 서울 2 memberB 19 울산 이런 상황에 엔티티로 매핑하고 증가시키면 자동으로 id는 3부터 이어서 시작이 되는걸까요?
-
미해결자바 ORM 표준 JPA 프로그래밍 - 기본편
운영 db 와 테스트 db
운영중인 db 가 중요하기 때문에,로컬에서 테스트 db 를 h2 로 설정해서 엔터티 정의후 테이블 생성하고, 생성한 테스트 db 에 대해 dao 를 작성하고, 엔터티 코드 및 dao 코드의 올바른 작성 확인 후 운영 반영을 하고 싶습니다.실제 h2 를 테스트 db 로 해서 상기방식으로 개발하시나요?개발서버 환경이어도 임의로 테이블은 만드는건 안되기 때문에 로컬 개발환경에서 개발하는 방식에 대해 궁금해서 여쭤봅니다.
-
해결됨실전! 스프링 부트와 JPA 활용2 - API 개발과 성능 최적화
값 타입을 DTO에 넣는 방법?
안녕하세요 강사님! 강의 잘 듣고 있습니다. MemberDTO에 Address를 넣어주려고하는데, MemberDTO에 값 타입인 Address를 넣어주는 것보다 city, street, zipcode를 각각 따로 넣어주는게 나을까요? ( 코드로 작성해놓았습니다.) #1 코드 #2 코드 그리고 값 타입인 Address를 DTO에 명시하게 되면, 이것도 결국 엔티티를 직접 외부에 노출하는 것일까요?
-
미해결실전! 스프링 부트와 JPA 활용2 - API 개발과 성능 최적화
회원 조회 로직의 응답 형식에 대해 질문이 있습니다.
아래처럼 회원 조회 로직이 있을때 멤버 엔티티 정보를 스트림화 한뒤 멤버 디티오 형식으로 다시 설정하고 그걸 리스트화하는것까지는 의미상으로 이해가 가는데여 응답 클래스 Result<T> 객체를 만들어서 응답하는 이유가 무엇인가여? @GetMapping("/api/v2/members")public Result memberV2() { List<Member> findMembers = memberService.findMembers(); List<MemberDto> collect = findMembers.stream() .map(m-> new MemberDto(m.getName())) .collect(Collectors.toList()); return new Result(collect);}@Data@AllArgsConstructorstatic class Result<T> { private T data;}@Data@AllArgsConstructorstatic class MemberDto { private String name;}
-
해결됨실전! 스프링 부트와 JPA 활용1 - 웹 애플리케이션 개발
ValidateDuplicateMember 메소드와 트랜젝션 관련해서 질문입니다.
@Transactional 애노테이션을 붙인 메서드는 오버라이딩 할 수 있어야 하기때문에 ValidateDuplicateMember 메서드를 private 접근지정자를 설정하면 명시적으로 @Transactional 애노테이션을 해당 메서드에 붙일 수가 없는데,강사님께서 하신것처럼 클래스 레벨로 @Transactional(readOnly = true) 애노테이션을 붙이면 ValidateDuplicateMember 메서드는 트랜젝션이 적용이 안되는지 궁금합니다.만약 적용이 안된다면 접근 지정자를 protected 로 변경해서 사용해도 되는지 궁금합니다. ----------------------- 전체 소스코드 입니다. ------------------------------- @Service@Transactionalpublic class MemberService { @Autowired private MemberRepository memberRepository; /** * 회원가입 * @param member member entity * @return memberId */ public Long join(Member member) { ValidateDuplicateMember(member); memberRepository.save(member); /* * member를 영속화 할때 key를 member의 id로 설정 (generateValue) * member 객체의 id 필드에는 값이 채워져있는 것을 보장할 수 있음 */ return member.getId(); } @Transactional(readOnly = true) protected void ValidateDuplicateMember(Member member) { List<Member> findMembers = memberRepository.findByName(member.getName()); if (!findMembers.isEmpty()) { throw new IllegalStateException("이미 존재하는 회원입니다."); } } /** * 회원 전체 조회 * @return memberList */ @Transactional(readOnly = true) // 성능 최적화 public List<Member> findMembers() { return memberRepository.findAll(); } /** * 회원 단건 조회 * @param memberId memberId * @return findMember */ @Transactional(readOnly = true) public Member findOne(Long memberId) { return memberRepository.findOne(memberId); }}
-
미해결실전! Querydsl
동적쿼리 BooleanBuilder 질문
안녕하세요 강사님, 강의 잘 보고 있습니다. 해당 강의 다른영상에서의 질문에서 BooleanBuilder와 자바 8을 이용해서 체이닝이 가능한 코드를 봣었습니다. 영상강의처럼 BooleanExpression을 사용한 ageBetween은 null이 반환될 수 있어서 테스트시 age를 안 넣으면 NPE가 뜨더라구요. 그래서 아래처럼 BooleanBuilder 사용한 코드로 바꾸면 null에 무조건 안전하게 되는게 맞는건가요? public List<MemberTeamDto> search(MemberSearchCondition condition) { return queryFactory .select(new QMemberTeamDto( member.id.as("memberId"), member.username, member.age, team.id.as("teamId"), team.name.as("teamName"))) .from(member) .leftJoin(member.team, team) .where( usernameEq(condition.getUsername()), teamNameEq(condition.getTeamName()), ageBetween(condition.getAgeLoe(), condition.getAgeGoe())) .fetch();}private BooleanBuilder usernameEq(String username) { return nullSafeBuilder(() -> member.username.eq(username));}private BooleanBuilder teamNameEq(String teamName) { return nullSafeBuilder(() -> team.name.eq(teamName));}private BooleanBuilder ageGoe(Integer ageGoe) { return nullSafeBuilder(() -> member.age.goe(ageGoe));}private BooleanBuilder ageLoe(Integer ageLoe) { return nullSafeBuilder(() -> member.age.loe(ageLoe));}private BooleanBuilder nullSafeBuilder(Supplier<BooleanExpression> f) { try { return new BooleanBuilder(f.get()); } catch (Exception e) { return new BooleanBuilder(); }}private BooleanBuilder ageBetween(Integer ageLoe, Integer ageGoe) { return ageLoe(ageLoe).and(ageGoe(ageGoe));} 익셉션마다 BooleanBuilder 객체를 새로 만드는데, 객체를 생성할 때 드는 비용은 null을 위해서는 크게 상관이 없는거죠? 그리고, ageBetween 부분에서 강의는 파라미터를 int 타입으로 받는데, 테스트시 NPE가 나와서 Integer로 바꾸니 되더라구요. 이유가 원래 Integer타입을 int로 자동 언박싱하는 중에 null을 int에 넣지 못해서 NPE가 뜨는건가요?
-
미해결실전! 스프링 부트와 JPA 활용2 - API 개발과 성능 최적화
Dto 사용시기에 대한 질문
안녕하세요. 항상 강의 잘 듣고있습니다 ! 질문이 두가지 있습니다. 첫째, "어느 레이어에서 DTO로 반환하는가?" 입니다. 현재 강의에서는 controller 에서 repository 를 바로 di 해서 사용하고 있으므로 서비스 레이어가 존재하지않는 것 같습니다. 하지만 만약 서비스레이어가 존재한다면, 지금 컨트롤러에서 작업되고있는 dto 변환 로직이 서비스에 들어가는것인가요. 아니면 서비스까지는 entity 를 유지한채 controller 에서 dto 로 변환되는 로직이 들어가는걸까요? (물론 정답이 없는 아키텍쳐링에 대한 질문입니다만, 대체적으로 어떻게 사용하고있는지 그리고 영한님의 노하우에 대해 궁금합니다. 구글링과 여러 블로그들을 보면 보통 controller 가 아닌 service 에서 dto 를 변환하는것이 낫다고 하여 혼란이옵니다.) 둘째, "Create, Update같은 것에선 언제 DTO로 반환하는가?" 입니다. 흔히 서비스쪽에서 dto 를 변환한다고 하니, 이것을 가정하고 아래와같은 코드를 작성해봤습니다. [#1] Entity class XXEntity { String id, Sting name } class YYEntity { String id, Sting title, XXEntity xx } [#2] Repository SampleRepository 는 JPA 레포지토리 XXRepository, YYRepository [#3] Service XXService 는 XXRepository를 DI 해서 비지니스로직을 돌려 나온 Entity를 Dto를 반환한다. YYService 는 YYRepository를 DI 해서 비지니스로직을 돌려 나온 Entity를 Dto를 반환한다. [#4] Controller SampleController 의 createXY DI : XXService DI : YYService xId 를 이용하여 XXService에서 찾은 A를 YYService의 create 에 넣어 YY를 만들어 리턴한다. XXDto found = XXService.findById(id) XX foundToEntity = XXDto.toEntity() // <-- 서비스레이어에서 dto 를 반환할때, 이부분이 너무 불편합니다. YYDto saved = YYService.create(new YYY("a", "b", foundToEntity)) return saved 보통 ****** 에 XX의 entitiy가 들어가는데 만약 서비스로직에서 dto 로 변환해서 내려주고있다면, 현재 XX에서는 dto를 받고있으니 이걸 다시 entitiy방식으로 변환시켜서 넣어주어야 하는데, 이것이 매우 불편하고 왠지 이런 방식으로 하는게 아닌것같아서요. 이때도 마찬가지로 service쪽까지는 entity로 유지하다가, controller 에서 변환을 시켜야되는것인지 궁금합니다. <추가> 저는 지금 혼란이 오는 것이 DTO 란 무엇인가입니다."외부에 entity를 노출시키면안되기 때문에 dto 로 변환해야한다" 라는 것도 있지만, 레이어간 데이터 이동을 위해서 만들어진것이 dto이기도 하니 어떤측면에서 바라보며 사용해야할지 혼란이 옵니다. 도움을 부탁드립니다 !!
-
해결됨실전! 스프링 부트와 JPA 활용1 - 웹 애플리케이션 개발
안녕하세요 트랜잭션 처리에 관해 질문드립니다.
안녕하세요, 팀장님! 트랜잭션을 엔티티 매니저를 직접 다루는 리포지토리에서 하는 것이랑 서비스 계층에서 하는 것이랑 어떤 차이가 있나요?@Transactional을 서비스 계층이 아니라 리포지토리에서도 걸 수 있는데 서비스 계층에서 거는 이유가 궁금합니다. 그리고 MVC 강의 출시는 언제쯤 예상하시나요?ㅎㅎ 감사합니다.
-
해결됨자바 ORM 표준 JPA 프로그래밍 - 기본편
IDENTITY 전략 질문있습니다.
IDENTITY 전략을 사용하는 경우에는 PK값을 확인하려면 디비에 직접 들어가서 확인을 한다고 하셨고, JPA를 이용해 영속성 컨텍스트에서 관리할 때, persist를 호출하는 시점에 실제 쿼리를 날려준다는 것까지는 이해를 했습니다. Q1. 이때 플러시 과정이 일어나는지 궁금합니다. Q2. persist를 호출해서 쿼리를 날린 이후에 영속성 컨텍스트에서 관리하는 것처럼 쿼리들을 모아놓는 저장소에 저장이 되었다가 rollback을 하거나 commit이 되는 시점에서 이전에 persist로 인해서 생긴 변화는 더티 체크가 되는지, 된다면 어떻게 되는지 궁금합니다.
-
미해결자바 ORM 표준 JPA 프로그래밍 - 기본편
orphanRemoval과 cascade의 관계
안녕하세요 영한님 강의 정말 잘 듣고 있습니다! 다름이 아니라 orphanRemoval과 cascade의 명확한 차이를 공부하던 도중 이해가 가지 않는 것이 있어서 질문 드립니다! 환경은 Spring Boot 2.4.2 입니다. cascade는 엔티티의 상태변화를 전파하는 것이며, orphanRemoval는 연관관계가 끊어진 Entity는 자동으로 삭제하는 것으로 알고 있습니다. 근데 부모에서 orphanRemoval를 true로 설정 후, 컬렉션에서 자식 Entity를 삭제해도 Delete 쿼리가 아닌 update 쿼리가 발생했습니다. 그래서 여러가지 테스트 해보니 CascadeType.ALL 아니면 CascadeType.PERSIST시 orphanRemoval 이 정상적으로 동작하였습니다. 아래 코드에서 Board Entity에서 cascade 옵션을 지우면 update 쿼리가 발생하여 테스트는 실패하며, cascade 옵션을 ALL 또는 PERSIST을 사용하면 delete 쿼리가 발생하여 테스트가 정상적으로 통과합니다. 책의 p.311을 보면 orphanRemoval만 사용한 예제가 있는데 하이버네이트 버전이 올라가면서 변경된 것일까요? @Entity @NoArgsConstructor(access = AccessLevel.PROTECTED) @Getter public class Board { @Id @GeneratedValue private Long id; private String title; private String content; @OneToMany(mappedBy = "board", cascade = CascadeType.PERSIST, orphanRemoval = true) private List<Comment> comments = new ArrayList<>(); @Builder public Board(String title, String content) { this.title = title; this.content = content; } public Board addComment(Comment comment){ this.comments.add(comment); comment.setBoard(this); return this; } public Board removeComment(Comment comment){ this.comments.remove(comment); comment.setBoard(null); return this; } } @Entity @NoArgsConstructor(access = AccessLevel.PROTECTED) @Getter public class Comment { @Id @GeneratedValue private Long id; private String comment; @ManyToOne @Setter private Board board; @Builder public Comment(String comment) { this.comment = comment; } } @DataJpaTest(properties = "classpath:application-test.yml") class BoardTest { @Autowired BoardRepository boardRepository; @Autowired CommentRepository commentRepository; @DisplayName("orphanRemoval 테스트") @Test @Rollback(false) public void orphanRemovalTest(){ Board board = Board.builder().title("1번글").content("1번글 컨텐츠").build(); boardRepository.save(board); Comment comment = Comment.builder().comment("1번글 댓글").build(); board.addComment(comment); commentRepository.save(comment); entityManager.flush(); entityManager.clear(); Board board1 = boardRepository.findById(board.getId()).get(); board1.removeComment(board1.getComments().get(0)); List<Comment> commentAll = commentRepository.findAll(); assertThat(commentAll.size(), is(0)); } }
-
미해결실전! 스프링 부트와 JPA 활용1 - 웹 애플리케이션 개발
수강을 시작하기 전에 한 가지 질문을 드립니다.
안녕하세요 강사님, 이번 강의도 잘 듣겠습니다.이번 강의를 본격적으로 시작하기 전에 질문을 하나 드리려고 합니다. 저는 현재 강사님의 스프링 입문편, 기본편, HTTP 강의를 완강한 상태입니다. 이제부터는 강사님께서 추천해주신 야생형 코스로 JPA 로드맵을 수강하고자 하는데요.이번 강의를 어떤식으로 공부하는게 좋을지 고민입니다. 저는 아직 JPA 기본편을 듣지 않았기 때문에 JPA에 대한 사전지식이 전무합니다. 이런 상황에서 활용편 강의를 수강하게 되면 분명히 막히는 부분이 많이 나오겠지요. 그럴 때마다 그런 부분들에 대한 이해를 하기 위해 노력하면서 들어야 할까요? 아니면 이해가 안 되는 부분은 그냥 따라치기만 하면서 넘어가고 나중에 기본편 학습 후 다시 돌아왔을때 철저한 이해를 목표로 수강하는게 좋을까요? ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ 추가적으로, JPA라는 기술에 대한 질문을 하나 더 드리고 싶습니다. 흔히들 말하는 국내 대표 IT 서비스 기업 "네카라쿠배" 같은 곳에서는 JPA 기술이 활발하게 사용될 것이라는 생각이 듭니다. 그러나 취업을 준비하는 취준생 입장에서 이러한 탑급 IT 기업만을 목표로 하여 JPA에만 집중하는 것이 맞는지에 대한 고민이 있습니다. 갈 수만 있다면 자체 IT 서비스를 운영하는 저런 거대 기업들에 가는 것이 좋기야 하겠지만.. 국내 대형 SI 기업들, 그 외 대기업 계열사들, 다른 중견기업들 등 최대한 포괄적으로 준비하여 "취업 1승"에 대한 성공 확률을 최대한 높이고 싶은 것이 불안한 취준생의 마음입니다. 이러한 측면에서 보았을 때, 최신 트렌드인 JPA만 공부하기 보다는 아직 그렇지 못한 기업들을 함께 고려하여 MyBatis 등의 기술도 준비해서 프로젝트를 진행해보는게 맞는 것인가? 하는 생각이 듭니다. 질문의 핵심은 이것입니다. "네카라쿠배 등의 IT 기업 외에 다른 곳들에서 JPA를 활발하게 사용하나요? 그렇지 않다면 다른 곳들에서 가장 활발히 사용되는 기술은 무엇인가요?" 물론 강사님께서 모든 기업에 근무하셨던 것은 아니니 전부 빠삭하게 꿰차고 답변을 주시기는 어렵겠지만.. 그래도 현직 베테랑 개발자의 입장에서 저같은 취준생에게 조언을 해주실 수 있는 부분이 있지 않을까 싶어서 질문을 남깁니다. ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ 부디 조언을 부탁드립니다. 감사합니다.
-
해결됨실전! 스프링 부트와 JPA 활용2 - API 개발과 성능 최적화
form, DTO 차이
안녕하세요 강사님. 공부를 하던중 form 과 DTO에 차이에 대해 궁금한점이 생겨 질문 드립니다. form은 아래와 같이 컨트롤러에서 Model에 담아 뷰에 전달 할때 사용하셨고 DTO는 아래와 같이 데이터를 반환할때 엔티티를 DTO로 변환하여 사용하셨는데 이때, 위의 경우처럼 form과 DTO가 사용되는 영역이 완전히 다른것인가요?? 예를들어, memberForm이 memberDTO로써 역할을 수행할 수 있다면 DTO로도 사용해도 되는것인가요? 제가 생각했을 땐 form은 validation이 들어갈 수 있기 때문에 DTO로 사용하면 안될것 같기도하면서도 그냥 DTO로 사용해도 될 것 같기도 하고 의문이 들어 질문드립니다. 항상 좋은 강의 감사드립니다.
-
미해결실전! 스프링 부트와 JPA 활용2 - API 개발과 성능 최적화
API Response Header
안녕하세요 영한님! API Response를 리턴할때 header를 포함하고싶을때 어떻게 해야할까요? 제네릭으로 Header를 따로 만들어야하는지, HTTPSERVLETRESPONSE를 이용해야하는지 궁금합니다. 고맙습니다! 건강하세요
-
해결됨실전! 스프링 부트와 JPA 활용2 - API 개발과 성능 최적화
조회 API 질문 드립니다!
안녕하세요 강의를 잘 듣고 있습니다. 조회 API 를 만들때, 제네릭으로 json 리스트 형태를 감싸서리턴을 하는데, 보통 조회API 는 단건 조회가 아닌 이상 리스트형태로 리턴을 할텐데, 이런 조회 API 에서는 제네릭으로 리스트를 한번 감싼 뒤 리턴을 해야한다. 로 이해해도 될까요? @GetMapping("/api/v2/members") public Result<List<MemberDto>> memberV2() { List<MemberDto> memberDtos = new ArrayList<MemberApiController.MemberDto>(); List<Member> findMembers = memberService.findMembers(); for(Member member : findMembers) { memberDtos.add(new MemberDto(member.getName())); } return new Result<List<MemberDto>>(memberDtos.size(), memberDtos); } @Data @AllArgsConstructor public static class Result<T>{ private int count; private T data; } @Data @AllArgsConstructor public static class MemberDto{ private String name; }
-
미해결실전! 스프링 부트와 JPA 활용1 - 웹 애플리케이션 개발
cannot resolve column 'Object'
이렇게 빨간줄이 떠서 신경쓰이시는 분들은 Settings -> Editor -> Inspections 에서 Unresolved database를 검색 -> Unresolved database references in annotaions 를 체크 해제 하시면 빨간줄이 없어집니다. IntelliJ가 너무 꼼꼼하게 검사를 해주기 때문에 발생한다고 합니다. 출처: https://log-laboratory.tistory.com/285
-
미해결실전! 스프링 데이터 JPA
즉시로딩 처리 시 findAll()일 경우 동작이 안되는 이유가 궁금합니다.
강의 중에는 실무에선 즉시로딩을 사용하지 말라고 하셨지만 테스트 차원에서 즉시로딩으로 findAll()을 조회하면 내부에서 left outer join이 걸리는 않는 현상을 확인했습니다. 동일한 조건에서 findById()로 처리하면 left outer join이 걸립니다. OneToMany, ManyToOne 모두 동일하게 동작을 하던데 혹시 이렇게 동작되는 이유가 있을까요??? 미리 답변 감사드립니다.
-
미해결실전! 스프링 부트와 JPA 활용1 - 웹 애플리케이션 개발
OrderItem을 DB에서 지우고자 할 때
안녕하세요. 주신 예제로 여러 가지 응용을 해보고 있는데, 한 가지 질문이 있어 질문드립니다. OrderItem을 지우는 상황을 가정을 했을 때, 지우는 방법에 대해 여쭤보고 싶습니다. (parent에 의존하여 영속화 되어있는 객체를 지우는 상황) Order를 지우면 OrderItem은 CASCADE 옵션 덕분에 잘 지워지지만, 반대로 Order는 두고 OrderItem 하나만 지우기 위해 Order <-> OrderItem 관계를 끊어도 OrderItem은 지워지지 않습니다. 아래는 제가 시도했던 부분입니다. - Parent인 Order의 list에서 OrderItem 삭제 - Child인 OrderItem에서 this.order = null; this.item = null;로 모든 관계 삭제 - @OneToMany 옵션이 있는 Parent쪽에서 orphanRemoval = true 옵션 넣기 - 위 과정 모두 한 뒤, em.persist(Order); 호출 위 모두 해보아도 OrderItem에 null로 들어갈뿐 OrderItem이 삭제 되진 않습니다. 구글링을 해봤을 땐 orphanRemoval 옵션 추가하고 연관관계 삭제하라는 말뿐이네요.. 혹시 방법이 있을까요? 그리고 추가로, 여기선 OrderItem이라는 다:1 매핑된 객체는 CASCADE를 통해 따로 영속화하지 않았는데, 보통 다:1 매핑은 전부 그러한가요? 제가 느끼기엔 서로 독립적으로 저장해야할 때라고 판단하였는데, 다:1이면 독립적일 수가 없을 것 같더라구요. 어떤 경우에 따로따로 영속화하고, 어떤 경우는 이 예시와 같이 한꺼번에 하는지 궁금합니다. 감사합니다.
-
미해결실전! 스프링 부트와 JPA 활용2 - API 개발과 성능 최적화
update 중복 회원 검출
안녕하세요 선생님! 매번 좋은 강의 잘 듣고 있습니다 ㅎㅎ 강의에 매료되어 남은 강의 모두 구매해버렸어요!! 덕분에 너무 재미있게 학습하고 있습니다 ^^ 회원 수정 부분에 동일이름 회원 중복 검출이 안 되는 것 같아 다음 내용을 추가하면 되는 것인 지 궁금합니다. MemberService.java /** * 회원 수정 */ @Transactional public void update(Long id, String name) { Member member = memberRepository.findOne(id); validateDuplicateMember(member); // 추가한 부분 member.setName(name); } 좋은 강의 만들어 주셔서 감사합니다.
-
해결됨실전! Querydsl
개인 프로젝트 시작을 어떻게 하면 좋을까요?
안녕하세요! 스프링 부트와 JPA 실무 완전 정복 로드맵 강의를 완강한 학생입니다. 배운 내용을 바탕으로 토이 프로젝트를 시작하려고 하는데, 개발 경험이 없어서 어떻게 시작해야 할 지 감이 안잡히네요 ㅠㅠ 조언을 구하고 싶어서 질문을 드립니다... 프로젝트 목적은 취업 포트폴리오로 활용하는 것입니다. 1. 클론 코딩 vs 직접 만들기 1) 클론코딩을 하면 어떻게 설계하고 어떤 것들을 구현해야 할 지 쉽게 파악할 수 있을 것 같아서 좋은 것 같은데, 한편으로는 이미 누군가가 구현한 것을 따라한 수준 밖에 안될 것 같아서 취업 포트폴리오로 활용할 수 있을까 걱정이 되네요... 2) 반면에 직접 만들어보면 학습, 설계 ,구현 등 모든 것을 "스스로" 했다는 것을 어필할 수 있을 것 같지만, 퀄리티가 많이 떨어질 것 같아서 고민입니다 2. 프론트 부분 처리 (API vs thymeleaf로 화면 출력) 1) API로 구현하면 아무래도 화면 처리에 대한 부담이 줄어들어서 백엔드 구현에 더 집중할 수 있을 것 같습니다. 하지만 취업 포트폴리오 목적으로 하는 것이니 만큼 화면까지 엮어서 구현을 해야 좀 더 있어보일 것 같은데, API만 구현하면 좀 부족해보이지 않을까 하는 걱정이 됩니다. 2) thymeleaf를 이용해서 html, css까지 엮어서 화면 출력을 하면 API와는 반대로 좀 더 있어보이는 포트폴리오를 만들 수 있겠지만, 백엔드 부분의 완성도가 떨어지지 않을까 하는 걱정이 됩니다. 아니면 html 무료 템플릿에 thymeleaf만 적용해서 만들어도 괜찮을까요? 물론 정해진 답은 없겠지만, 각각의 선택지에 대해서 어떠한 장단점이 있는지, 어떠한 점들을 고려해야 하는지 알고 싶습니다. 개발 경험이 없어서 무엇을 여쭤봐야 할 지도 모르겠네요 ㅎㅎ.. 강의를 들으면서 정말 많은 것들을 배웠습니다! 항상 친절하고 자세한 설명 감사합니다^^