[질문 템플릿] 1. 강의 내용과 관련된 질문인가요? (예) 2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예) 3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예) [질문 내용] @Test @Transactional @Rollback(value = false) public void testMember() throws Exception { //given System.out.println("given"); Member member = new Member(); member.setUsername("memberA"); //when System.out.println("when"); Long saveId = memberRepository.save(member); Member findMember = memberRepository.find(saveId); //then System.out.println("then"); Assertions.assertThat(findMember.getId()).isEqualTo(member.getId()); Assertions.assertThat(findMember.getUsername()).isEqualTo(member.getUsername()); Assertions.assertThat(findMember).isEqualTo(member); } 위의 코드에서 @Rollback(value = false) 없이 돌렸을때, given when 2023-10-23T22:09:28.313+09:00 DEBUG 13164 --- [ main] org.hibernate.SQL : select next value for member_seq then @Rollback(value = false) 을 넣고 돌렸을 때, given when 2023-10-23T22:10:13.319+09:00 DEBUG 18292 --- [ main] org.hibernate.SQL : select next value for member_seq then 2023-10-23T22:10:13.456+09:00 DEBUG 18292 --- [ main] org.hibernate.SQL : insert into member (username,id) values (?,?) 위와 같이 출력됩니다. 이 현상에 대해 제가 생각하는 원인은 다음과 같습니다. 트랜잭션이 커밋될 때 (특정 상황 제외), 영속성 컨텍스트의 sql문들이 DB로 전송되므로, @Rollback(value = false) 없는 상태에선 저장된 sql문들이 전달되지 않고 메모리에서 삭제되는 것으로 추론하고 있습니다. 저의 생각이 맞는지 궁금합니다.
- 학습 관련 질문을 남겨주세요. 상세히 작성하면 더 좋아요! - 먼저 유사한 질문이 있었는지 검색해보세요. - 서로 예의를 지키며 존중하는 문화를 만들어가요. - 잠깐! 인프런 서비스 운영 관련 문의는 1:1 문의하기를 이용해주세요. 강의에 보면 enum에 TEST라고 하시고 에러메시지를 정적으로 입력하셨는데 , 메시지properties로 따로 관리하는 방법은 없을까요? TEST(HttpStatus.INTERNAL_SERVER_ERROR,"001",messageSource.getMessage("001")), 001 = "business Exception test" 돌아가는 코드는 아니지만 이런식으로 답변 주시면 감사하겠습니다
[질문 템플릿] 1. 강의 내용과 관련된 질문인가요? 예 2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? 예 3. 질문 잘하기 메뉴얼을 읽어보셨나요? 예 [질문 내용] 연관관계의 주인을 외래키에 두라고 하신말씀은 알겠습니다.그것이 일대다 인경우는 자동차와 바퀴의 예를 들면서 말씀해주셔서 알겠는데 1대1관계의 경우 어느쪽이 외래키라고 할수 있는걸까요? 오더와 딜리버리의 경우에 오더가 관계의 주인이 되었는데 왜? 라고 물으면 잘 모르겠습니다 만약에 예를들어 유저와 유저정보간의 관계가 있다면 그경우의 연관관계의 주인은 어떤것일까요? 기준을 좀만 더 정확하게 알려주셨으면 좋겠습니다...
[질문 템플릿] 1. 강의 내용과 관련된 질문인가요? (예) 2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예) 3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예) [질문 내용] 강의 잘 듣고 있습니다! 학습을 위해 예제 코드를 조금 응용해서 TODO 앱를 만들어보고 있는데 의도한 기능대로 작동이 안 됩니다. 강의 내용과는 조금 방향이 다르지만 BindingResult 관련 질문이기도 하고 하루종일 해봐도 모르겠어서 질문 올립니다. 강의 예제의 [회원 가입] 폼에서 이름을 비워두고 제출한 경우 @Valid 검증 오류가 발생 하여 return "members/createMemberForm" 되고, View에서 <p th:if="${#fields.hasErrors('name')}" th:errors="*{name}"><p> 가 삽입되면서 MemberForm 의 @NotEmpty 에러 메세지가 출력되는 기능을 조금 바꿔서 해 수정 기능에 적용해 보려고 했습니다. 의도한 기능은 이렇습니다. (코드는 밑에 있습니다) 할 일(task) 수정을 누르면 @GetMapping("/tasks/{taskId}/edit") 와 매핑된 메서드가 전달된 파라미터의 taskId 로 할일 객체를 찾아 TaskForm (할일 Form 객체)에 값을 세팅합니다. 그리고 이 TaskForm 객체를 Model 에 "form" 이라는 이름으로 값을 담아 전달합니다. View(할일 수정 폼)에서 수정하고자 하는 할일의 현재 name 값, priority 값를 보여줍니다. (수정을 위해 현재 값을 표시해줌) 수정 폼을 채우고 제출을 누르면 @PostMapping("/tasks/{taskId}/edit") 에 매핑됩니다. 만약 검증에 오류가 있는 경우 return "task/editTaskForm"; 를 합니다. 즉 editTaskForm.html 문서를 엽니다. 문제 상황 : 그런데 editTaskForm.html 파싱에 실패합니다. 해당 Task의 현재 값을 미리보기 해주려면 ${form.name} 을 참고해야 하는데 form 이 넘어가지 않아서 인 것 같습니다. 그래서 @SessionAttributes("form") 로 세션에 저장해주었습니다(스프링 2.7입니다). 2. 이제 파싱은 되고 해당 Task의 현재 값 미리보기도 됩니다. 그런데 여전히 <p> 태그가 생성되지 않아서 오류 메세지도 출력이 안 됩니다. BindingResult 가 날아간 것 같습니다. 3.방법을 바꿔서 View를 바로 여는 게 아니라 @GetMapping 으로 리다이렉트를 해보았는데 역시 Model 이 초기화되면서 BindingResult 가 날아가는 것 같습니다 ㅠㅠ 검색해보니 RedirectAttributes 를 써야 한다는데 저는 강의와 똑같이 스프링 2.7을 쓰고 있는데 3.1 미만 버전에서는 GET 파라미터로 전달하는 것 외엔 방법이 없을까요? @Controller @RequiredArgsConstructor @SessionAttributes("form") public class TaskController { private final TaskService taskService; @ModelAttribute("form") public TaskForm getTaskFrom() { return new TaskForm(); } @GetMapping("/tasks/{taskId}/edit") public String editTaskForm(@PathVariable Long taskId, Model model) { Task task = taskService.findOne(taskId); TaskForm form = new TaskForm(); form.setName(task.getName()); form.setPriority(task.getPriority()); model.addAttribute("form", form); return "task/editTaskForm"; } @PostMapping("/tasks/{taskId}/edit") public String editTask(@PathVariable Long taskId, @Valid TaskForm form, BindingResult result, SessionStatus sessionStatus) { if (result.hasErrors()) { return "task/editTaskForm"; } taskService.editTask(taskId, form.getName(), form.getPriority()); sessionStatus.setComplete(); return "redirect:/tasks"; } } JPA 활용 2편까지도 들었고 MVC 1까지도 들었는데.. MVC 2의 BindingResult 강의를 듣고 다시 해보는게 좋을까요? 하지만 너무 해결하고 싶습니다.........🥺 어느 부분을 체크해보면 좋을까요?
public enum Tier { CHALLENGER("challenger"), GRANDMASTER("grandmaster"), MASTER("master"), DIAMOND("diamond"), EMERALD("emerald"), PLATINUM("platinum"), GOLD("gold"), SILVER("silver"), BRONZE("bronze"), IRON("iron"), NULL("null"); private final String tier; Tier(String tier) { this.tier = tier; } } 이런 enum을 필드로 가지고 있는 entity가 있습니다. public class MyEntity { ... @NotNull @Column(name = "queue", columnDefinition = "VARCHAR(20)") @Enumerated(EnumType.STRING) private Tier queue; ... } 그런데 querydsl로 이 enum기준으로 custom sort를 할 경우에는 어떻게 해야하나요? 예를 들면 enum Tier에 적혀있는 순서대로 CHALLENGER > GRANDMASTER > ... > NULL 순서대로 정렬할 때 어떻게 해야하는지 궁금합니다!
김영한 강사님 추천 로드맵 수강 순서를 보면 JPA1편 -> 기본편 -> JPA1편 복습 -> JPA2편으로 되어있는데요 제 시간 사정상 최대한 빨리 익혀야 하기도 하고, API 설계나 DTO가 너무 궁금해서 곧바로 JPA2편으로 학습하고 싶습니다. JPA1편에서 모르는 개념들(영속성 컨텍스트, 머지, 도메인 설계)이 많아서 우선 그냥 코드 따라하기 식으로 하고 있는데요 JPA2편까지 따라하다가 기본편 다시 봐도 될까요?
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요. 1. 강의 내용과 관련된 질문을 남겨주세요. 2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요. (자주 하는 질문 링크: https://bit.ly/3fX6ygx) 3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요. (질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG) 질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요. ========================================= [질문 템플릿] 1. 강의 내용과 관련된 질문인가요? (예) 2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예) 3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예) [질문 내용] @GeneratedValue어노테이션을 설명에 맞게 바꾸다가 IDENTIFY로 변경후에 아래와 같이 메시지가 발생합니다. ERROR: NULL not allowed for column "ID"; SQL statement: 소스는 아래와 같습니다. // Member.java @Entity public class Member { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; //.. } Persistence.xml <?xml version="1.0" encoding="UTF-8"?> <persistence version="2.2" xmlns="http://xmlns.jcp.org/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence http://xmlns.jcp.org/xml/ns/persistence/persistence_2_2.xsd"> <persistence-unit name="hello"> <properties> <!-- 필수 속성 --> <!--생략...--> <property name="hibernate.dialect" value="org.hibernate.dialect.H2Dialect"/> <!-- 옵션 --> <!--생략...--> <property name="hibernate.hbm2ddl.auto" value="create" /> </properties> </persistence-unit> </persistence> //Main메서드 내용입니다 public static void main(String[] args) { EntityManagerFactory emf = Persistence.createEntityManagerFactory("hello"); //위에 메니저팩토리를 불러오는순간 웬만한 작업 가능. EntityManager em = emf.createEntityManager(); EntityTransaction tx = em.getTransaction(); tx.begin(); try{ Member member = new Member(); member.setName("CCCC"); System.out.println("============start=========="); em.persist(member) ; System.out.println ("member.getId() = " + member.getId()); tx.commit(); //...생략 h2콘솔에서 테이블은 정상적으로 생성되어있는 상태입니다.
[질문 템플릿] 1. 강의 내용과 관련된 질문인가요? (예) 2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예) 3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예) [질문 내용] 비울 지.. 안 비울 지.. 전송해 버려서 가지고 있을 필요가 없는 것 같으면서도.. 그렇다고 그게 그렇게 큰 메모리는 차지하고 있지는 않을 거기 때문에.. 가지고 있는 이점이 뭔지는 모르겠지만, 뭔가 이점이 있어서 안 지울 것 같기도 하고..
[질문 템플릿] 1. 강의 내용과 관련된 질문인가요? 예 2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? 예 3. 질문 잘하기 메뉴얼을 읽어보셨나요? 예 [질문 내용] Category 에 parent와 child의 역할이 뭔지 수업을 듣고도 잘 모르겠습니다 단순히 부모카테고리 자식카테고리로 알고있으면 되는걸까요? 이렇게 만들면 연결된 items 하고도 부모카테고리와 자식카테고리가 어떻게 엮이는지 잘 이해가 안갑니다
[질문 템플릿] 1. 강의 내용과 관련된 질문인가요? (예) 2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예) 3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예) [질문 내용] persist 하면 캐시에 저장됨과 동시에 그 내용이 SQL로 해석되어 쓰기 지연 SQL 저장소에 저장되잖아요. 그런데 중간에 영속화 했던 것의 값을 바꾸면 updata문이 또 추가가 될거 잖아요. (커밋 시점에 비교하는 거니 한번만. 물론 보통 persist 전에 모든 작업을 끝내놓는게 바람직 하지만) 그런 것 보다는 차라리 캐시 될 때 쓰기 지연 SQL 저장소에다 SQL문으로 해석하여 저장하는 것 보다, 커밋 순간에 캐시에 있는 내용들을 SQL문으로 해석하는 것은 별로일까요? 그러니까, member 객체를 select문에서 가져온거면 enum.select, 새로 생성한 거면 enum.create라고 해서 추가로 그렇게 묶어서, 캐시에 저장할 때는 원래 member 객체 reference를 가지고 있도록 한 다음 객체 하나로 감싸서 저 enum을 가지고 있게 한다던지, (초기상태 캡쳐도 한다고 했는데, 그럼 원래 이런 식인건가..? Member prototype 해서..?) 마지막에 commit 순간에 영속성 컨텍스트를 읽어 SQL문으로 해석하고 만약 enum.create면 그냥 최신값 그대로 쿼리문으로 만들어서 날리면 되고 update면 현재값 그대로 날리면 되고 select면 이거는 똑같고. 전체적으로 보니 그냥 이거 모두를 select 처럼 commit 시점에 한번 확인만 하고 영속성 컨텍스트에 있는 모두를 한번에 쿼리로 바꿔 내보내는 것이요. 근데 이거 아직 join 이런 게 잘 몰라서 그런 쪽에서 문제가 있을 수 있겠나요?
질문드립니다. 각각 다른 데이터베이스에 있는 테이블을 엔티티로 만들어서 둘간의 관계를 구성할 수 있을까요? 조금 더 설명을 드려보면 하나의 MySQL 서비스에 A1 이라는 DB 와 A2 라는 DB 를 각각 만들어서 운영중이라고 하면 A1.Table1 과 A2.Table2 가 각각 엔티티로 구성되고, 그것의 관계설정에는 문제가 없는지 가능하다면 어떤 방법을 사용하면 좋을지 궁금합니다. 단 DB 에 연결되는 계정은 두개의 DB (A1, A2) 모두에 권한을 가지고 있는 상황입니다. 혹시 방법이 있을지 문의드립니다. 감사합니다.
[질문 템플릿] 1. 강의 내용과 관련된 질문인가요? 예 2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? 예 3. 질문 잘하기 메뉴얼을 읽어보셨나요? 예 [질문 내용] 다대다 관계는 실무에서 한계가 크다는걸 배우고 다대일 일대다 관계로 중간엔티티 CategoryItem을 만들어서 해보려고 하는데 그떄 어떻게 연관관계를 짜면 될까요? 어떤컬럼을 어떤식으로 받아오면되는지 헷갈립니다...
Interface를 이용하여 완충재를 두고 테스트를 할 때는 테스트를 위한 mock 구현체를 이용하여 final 메소드를 stub하는 것을 피한다는 것은 이해를 했는데요. 갑자기 드는 생각이 결국 프로젝트가 배포될 때는 SystemUuidHolder라는 구현체를 사용하게 되고 그러면 해당 클래스의 대한 테스트도 진행해야 하나요? 진행한다면 해당 클래스는 UUID를 사용하고 있으니 final 메소드를 stub하는 상황을 피할 수 없게 되는건가요?
안녕하세요. 회사 신규 프로젝트로 Spring Boot와 JPA를 이용해 백엔드를 개발하고 있는 직장인입니다. 원래 C#개발자다 보니 수업을 들으며 차근차근 따라가 보지만 의외의 경우가 발생해 힘들지만 좋은 강의에 항상 재밌게 배우고 있습니다. 이번에 문의드릴 내용은 fetch join된 table에 다시 fetch join 하는 방법에 대해 문의 드리고자 합니다. 문제의 테이블 구조입니다. Count Table과 Contract Table은 company_code라는 pk로 N:1구조 Contract Table은 Company Table과 company_code라는 pk로 N:1구조 로 구성돼 있습니다. 그리고 Count, Contract Table은 매핑되는 키에 대해서 FetchType을 Lazy로 설정한 상태입니다. 저는 여기서(JPQL기준) Count Table을 기준으로 Contract Table까지는 fetch join에 성공했지만 추가로 Company관련 쿼리가 N+1처럼 추가됐습니다. 혹시 제가 JPQL혹은 Query DSL방법으로 Contract Table과 Company Table을 fetch join 처리 후 다시 Count Table과 fetch join해 쿼리 하나로 해결 할 수 있는 방법이 있을까요? 감사합니다. :D
안녕하십니까 영한님. 강의 유익하게 잘 들었습니다. 덕분에 궁금증이 많이 해결되었습니다. 다름이 아니라, 제가 Pageable를 사용한 페이징 기능을 테스트 해보는 과정에서 sort의 property에 실질적인 entity 정보가 노출된다고 생각되어 고민에 빠진 상태입니다. 페이징 관련된 파라미터를 dto로 받게되면 유효성 검사는 가능하나 sort의 순서를 보장하기 어려워 추가적인 파라미터가 필요하다고 생각됨. pageable로 받은 후 for문을 돌려 유효성 검사를 하게 되면 하위의 단계로 나눠지는 불편함 1) controller에서 dto로 유효성 검사를 위한 for문 2) entity는 service에서만 사용하게끔 유도하기 위해 controller에서는 유효성 검사가 끝난 dto를 service로 넘겨서 entity로 재조립하는 for문 등등 여러가지 방법들을 고민해보다 질문드립니다. 실질적으로 실무에서 사용되는 Paging 기법이 있거나 개선 사항이 있으면 공유해주시면 감사하겠습니다.