묻고 답해요
138만명의 커뮤니티!! 함께 토론해봐요.
인프런 TOP Writers
-
미해결실전! 스프링 부트와 JPA 활용1 - 웹 애플리케이션 개발
테스트 exception 관련 질문 입니다.
안녕하십니까 선생님의 강의 정말 유익하게 잘 보고 있습니다. 다름이아니라 상품주문 test 를 하게되면 ==== 오류 org.springframework.dao.InvalidDataAccessApiUsageException: id to load is required for loading; nested exception is java.lang.IllegalArgumentException: id to load is required for loading 이런식으로 납니다.그래서 id가 자동으로 생성이 안되는내용이라서 @GenereatedValue 가 이미 Item 에 id 에 선언되어있고 혹시나 해서 setId로 id 값 지정후 해보니 그다음으로는 == 오류 전문 java.lang.NullPointerException at jpabook.jpashoop.service.OrderService.order(OrderService.java:41) at jpabook.jpashoop.service.OrderService$$FastClassBySpringCGLIB$$f6e85b24.invoke(<generated>) at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:218) at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:771) at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163) at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:749) at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:367) at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:118) at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:749) at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:691) at jpabook.jpashoop.service.OrderService$$EnhancerBySpringCGLIB$$ac50f3a2.order(<generated>) at jpabook.jpashoop.service.OrderServiceTest.상품주문(OrderServiceTest.java:44) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.base/java.lang.reflect.Method.invoke(Method.java:566) at org.junit.platform.commons.util.ReflectionUtils.invokeMethod(ReflectionUtils.java:686) at org.junit.jupiter.engine.execution.MethodInvocation.proceed(MethodInvocation.java:60) at org.junit.jupiter.engine.execution.InvocationInterceptorChain$ValidatingInvocation.proceed(InvocationInterceptorChain.java:131) at org.junit.jupiter.engine.extension.TimeoutExtension.intercept(TimeoutExtension.java:149) at org.junit.jupiter.engine.extension.TimeoutExtension.interceptTestableMethod(TimeoutExtension.java:140) at org.junit.jupiter.engine.extension.TimeoutExtension.interceptTestMethod(TimeoutExtension.java:84) at org.junit.jupiter.engine.execution.ExecutableInvoker$ReflectiveInterceptorCall.lambda$ofVoidMethod$0(ExecutableInvoker.java:115) at org.junit.jupiter.engine.execution.ExecutableInvoker.lambda$invoke$0(ExecutableInvoker.java:105) at org.junit.jupiter.engine.execution.InvocationInterceptorChain$InterceptedInvocation.proceed(InvocationInterceptorChain.java:106) at org.junit.jupiter.engine.execution.InvocationInterceptorChain.proceed(InvocationInterceptorChain.java:64) at org.junit.jupiter.engine.execution.InvocationInterceptorChain.chainAndInvoke(InvocationInterceptorChain.java:45) at org.junit.jupiter.engine.execution.InvocationInterceptorChain.invoke(InvocationInterceptorChain.java:37) at org.junit.jupiter.engine.execution.ExecutableInvoker.invoke(ExecutableInvoker.java:104) at org.junit.jupiter.engine.execution.ExecutableInvoker.invoke(ExecutableInvoker.java:98) at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.lambda$invokeTestMethod$6(TestMethodTestDescriptor.java:212) at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.invokeTestMethod(TestMethodTestDescriptor.java:208) at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:137) at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:71) at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$5(NodeTestTask.java:135) at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$7(NodeTestTask.java:125) at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:135) at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:123) at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:122) at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:80) at java.base/java.util.ArrayList.forEach(ArrayList.java:1540) at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:38) at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$5(NodeTestTask.java:139) at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$7(NodeTestTask.java:125) at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:135) at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:123) at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:122) at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:80) at java.base/java.util.ArrayList.forEach(ArrayList.java:1540) at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:38) at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$5(NodeTestTask.java:139) at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$7(NodeTestTask.java:125) at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:135) at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:123) at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:122) at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:80) at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.submit(SameThreadHierarchicalTestExecutorService.java:32) at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor.execute(HierarchicalTestExecutor.java:57) at org.junit.platform.engine.support.hierarchical.HierarchicalTestEngine.execute(HierarchicalTestEngine.java:51) at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:248) at org.junit.platform.launcher.core.DefaultLauncher.lambda$execute$5(DefaultLauncher.java:211) at org.junit.platform.launcher.core.DefaultLauncher.withInterceptedStreams(DefaultLauncher.java:226) at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:199) at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:132) at com.intellij.junit5.JUnit5IdeaTestRunner.startRunnerWithArgs(JUnit5IdeaTestRunner.java:71) at com.intellij.rt.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:33) at com.intellij.rt.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:220) at com.intellij.rt.junit.JUnitStarter.main(JUnitStarter.java:53) 이런식으로 NullPointEception 이 일어납니다.혹시 이렇게 되면 item class가 문제인지 또는 service 와 repository 문제인지 혹시 알고싶습니다.
-
미해결자바 ORM 표준 JPA 프로그래밍 - 기본편
team에서 member를 add할 이유가 이해가안갑니다.
어차피 조회만 가능하고, add 해봤자 무반응일텐데 왜 주인이 아닌쪽에서 regist가 아닌 add 작업을 꼭 해서 양방향성을 유지하는지....ㅠㅠ
-
해결됨실전! 스프링 부트와 JPA 활용1 - 웹 애플리케이션 개발
안녕하십니까? 도메인 설계시 인터페이스, 추상클래스 에 대한 의견을 듣고 싶습니다.
안녕하십니까? 강의 영상 모두 결제해서 잘 보고 있습니다. 바로 본론부터 말씀 드리면, 회사에서 여러개의 프로젝트를 준비하고 있고 그중 자주 쓰이는 공통적인 기능을 ( 회원, 게시판 등 ) 만들어 놓고 프로젝트마다 재활용하여 시간을 단축하자는 의견이 나왔습니다. 그래서 JPA 에서 사용하는 entity 도 인터페이스와 추상클래스를 사용해서 설계를 해보라고 해서 진행중에 있습니다. 들어가기 앞서, 스프링 프로젝트의 코드를 살펴보면 인터페이스를 잘 사용해서 설계를 잘 했다고 생각하고 있습니다.그러나 데이터베이스와 직접적인 연관이 없는 코드라서 자유롭게 쓸수 있었던것 같은데요. JPA 를 쓰고 있는 입장에서 인터페이스와 추상클래스를 사용해서 다형성을 구현할려고 할때마다 한계에 자꾸 봉착하는 느낌이 듭니다. 결국 도메인 클래스는 CRUD 가 중요한데, 인터페이스로는 실제 구현된 클래스가 뭔지 알수 없어 사용하기가 난감합니다. Item 과 Book 과 같이 강하게 결합 하는것에 대해서는 어느정도 수긍이 갑니다만, 거의 대부분은 그렇게 강하게 연결되는 경우가 잘 없는거 같아서요. 인터페이스를 쓰는경우도 잘 못본거 같습니다. 실무에서는 인터페이스와 추상클래스를 어느 정도 까지 사용하는지궁금합니다.
-
미해결실전! 스프링 부트와 JPA 활용1 - 웹 애플리케이션 개발
update에대한 질문입니다!
지금은 Book 상품등록, 상품수정의 기능만 한다고 하셨는데 영화와 음반까지 추가하려면 단순히 controller와 service에 메서드들을 추가해서 로직을 짜면 되는건가요? 아니면 메서드를 추가안하고 다른 방법이 있을까요?
-
미해결실전! 스프링 부트와 JPA 활용2 - API 개발과 성능 최적화
조회 v3.1에서 to One 관계는 모두 페치 조인하고 나머지 컬렉션은 지연로딩을 유지했을때 다음과 같은 에러가 발생합니다.
좋은 강의 감사합니다. 조회 v3.1에서 to One 관계는 모두 페치 조인하고 나머지 컬렉션은 지연로딩을 유지했을때 다음과 같은 에러가 발생합니다. query specified join fetching, but the owner of the fetched association was not present in the select list 고심하던 중 @Query부분을 value 와 countQuery로 나눠어서 처리 한 결과 정상적으로 조회 됬습니다.(Spring Data Jpa사용) 예) @Query(value = "select u from User u join fetch u.store s", countQuery = "select count(u) from User u") Page<User> findAllUser(Pageable pageable); 꼭 countQuery를 사용해야 하는지 궁금합니다.
-
미해결실전! 스프링 부트와 JPA 활용1 - 웹 애플리케이션 개발
thymeleaf 의 경로를 못찾는다고 나오네요
indx.html을 /src/main/resourcee/static/index.html을 넣어도 못찾네요 hello예제에서는 "template might not exist or might not be accessible by any of the configured Template Resolvers" 로 나오네요 경로가 차이가 있는건지 모르겠습니다. 아래는 grandle 설정입니다 어떤 문제가 있는건지 모르겠습니다. plugins { id 'org.springframework.boot' version '2.1.16.RELEASE' id 'io.spring.dependency-management' version '1.0.9.RELEASE' id 'java'}group = 'jpabook'version = '0.0.1-SNAPSHOT'sourceCompatibility = '1.8'configurations { compileOnly { extendsFrom annotationProcessor }}repositories { mavenCentral()}dependencies { implementation 'org.springframework.boot:spring-boot-starter-data-jpa' implementation 'org.springframework.boot:spring-boot-starter-thymeleaf' implementation 'org.springframework.boot:spring-boot-starter-web' compileOnly 'org.projectlombok:lombok' runtimeOnly 'com.h2database:h2' annotationProcessor 'org.projectlombok:lombok' testImplementation 'org.springframework.boot:spring-boot-starter-test'}
-
미해결실전! 스프링 부트와 JPA 활용1 - 웹 애플리케이션 개발
post vs put
안녕하세요. 보통 리소스를 수정하는데 put 메서드를 사용한다고 알고 있는데, post를 사용한 이유 같은게 있나요?
-
미해결실전! Querydsl
fetch join 관련 질문 드립니다!!
안녕하세요 영한님 올려주시는 강의를 들으며 JPA와 queryDsl을 공부중 입니다. 좋은 강의 감사합니다 :) 이것저것 해보는 과정중에 궁금증이 생겨 질문 드립니다. 먼저 Team 과 Member 엔티티를 단순화 해 보았습니다. @Entity public class Team { @Id @GeneratedValue @Column(name = "team_id") private Long id; private String name; private Integer rank; @OneToMany(mappedBy = "team") List<Member> members = new ArrayList<>(); } @Entity public class Member { @Id @GeneratedValue @Column(name = "member_id") private Long id; private String username; private int age; @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "team_id") private Team team; } (질문 1) Team과 Member는 서로 Lazy로 설정해 두었는데요 (Team에 rank 필드를 추가해 보았습니다.) 만약, Team을 조회 할때는 항상 Member가 필요 하다고 가정을 한다면(fetchJoin) rank가 5이상인 Team을 조회를 하면서 (Team은 항상 조회 -> left join) Team에 속한 Member의 나이가 20살 이상인 데이터를 즉시 조회 하고 싶다면 어떻게 작성 해야 할까요? 예를 들어 위의 조건은 sql로 아래와 같이 사용할수 있습니다. select * from team left join member on (team.id = member.id and member.age > 20) where team.rank > 5 위의 쿼리를 querydsl로 작성 한다면 아래와 같이 작성 가능 할것 같은데요 (fetchJoin 사용) QTeam team = QTeam.team; QMember member = QMember.member; JPAQUERY<Team> query = queryFactory.selectFrom(team) .distinct(); query.leftJoin(team.members, member) .on(member.age.gt(20)) .fetchJoin(); query.where(team.rank.gt(5)); 하지만 이를 querydsl로 작성하면 아래와 같은 오류가 발생합니다. witch-clause not allowed on fetched associations 찾아보니까 fetch 조인을 사용할 때는 on절을 사용할수 없다고 하더라구요.. 이런경우에 어떤 방법으로 해결할 수 있을까요? (질문 2) 아래 와 같이 조회를 했을때 QTeam team = QTeam.team; QMember member = QMember.member; JPAQUERY<Team> query = queryFactory.selectForm(team) .distinct(); query.leftJoin(team.members, member) query.where(team.name.eq("AAA") .and(member.age > 20)); Team의 데이터를 꺼내보면 ( name = 'AAA' ) 조건이 잘 적용되어 팀 이름이 AAA인 팀만 조회가 됩니다. 문제는 Lazy설정된 Member를 get() 할 때 인데요 Team.members를 get() 하면 Lazy 로딩이기 때문에 select 쿼리가 각각 다시 발생하는데 이때 ( age > 20 ) 조건이 적용 되지 않고 AAA Team에 속한 모든 Member가 조회 되어 집니다. 같은 트렌젝션에서 수행이 된다면 Member을 get()할때 ( age > 20 ) 조건이 적용될꺼라 생각했는데 조건 적용없이 모든 Member를 조회 해서 당황 스럽네요 이부분은 왜 조건문이 적용되지 않은 결과가 get() 되는 건가요?
-
미해결실전! 스프링 부트와 JPA 활용1 - 웹 애플리케이션 개발
Category 계층 구조를 보고 질문드립니다.
안녕하세요. 영한님 강의 잘 듣고 있습니다. 감사합니다. Category Entity에서 parent와 child 만드는 것을 보고 게시판에서 댓글과 대댓글 관계를 생각해보았는데 댓글 Entity에서 대댓글을 List로 담고 똑같은 계층구조로 구현하는게 객체지향적인 설계가 맞을까요?
-
미해결실전! 스프링 부트와 JPA 활용2 - API 개발과 성능 최적화
안녕하세요. Unique Index 데이터 저장에 대해서 질문드립니다.
안녕하세요. 강의 잘 듣고 많은걸 배우고 있습니다. 현재 강의와는 안 맞을 수 있는내용이지만.. 많은 고민이 되어 질문드립니다ㅜ 예를들어 Team이라는 테이블이 있고, name이라는 Column이 Unique Index로 설정되어 있는 상태입니다. CrudRepository의 save 함수를 이용해 저장하고 있고 Custom Exception을 핸들링해서 "이미 저장되어 있습니다."라는 응답값을 반환하는것이 목표입니다. 현재 고민하고 있는 방법은 1. Insert 쿼리를 사용하기전에 이미 저장된 name이 있는지 Select 쿼리로 조회해 있다면 Custom Exception을 발생. -> 팀을 생성할때마다 Select 쿼리를 발생 2.try ... catch로 DataIntegrityViolationException을 잡아 Custom Exception 발생 -> DataIntegrityViolationException이 넓은 범위의 제약조건을 포함하고 있는 것으로 알고있어서 DuplicateKey ErrorCode로 잡아서 Custom Exception을 발생시켜야하나 싶습니다.. 혹시 실무에서는 위의 방법 중 하나 혹은 다른 방법을 사용해 어떤식으로 해결하는지 궁금합니다
-
미해결실전! 스프링 부트와 JPA 활용1 - 웹 애플리케이션 개발
셀프로 양방향 연관관계 관련 질문입니다.
안녕하세요, 먼저 강의를 잘 듣고 있는 학생 1인 입니다. ㅎㅎ 엔티티 클래스 개발2 강의 중 셀프로 양방향 연관관계 관련 질문입니다. Category 엔티티에서 // 자식입장에서 바라보는 부모 @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "parent_id") private Category parent; 위의 JoinColumn시 "category_id"가 아니라, "parent_id"로 작성해야 되는 이유를 알 수 있을까요? 셀프를 제외한 일반적인 양방향 연관관계에서 "연관관계 주인" 쪽에서 연관관계 거울 쪽을 Join할 때 연관관계 거울의 KEY를 명시해 주는데, 이와 마찬가지로 parent_id가 아닌 category_id가 아닌지... 궁금합니다. 실제로 바꿔서 했을 때, 오류가 발생했습니다...
-
미해결자바 ORM 표준 JPA 프로그래밍 - 기본편
임베디드 타입, @MappedSuperclass 관련 다른질문입니다!
안녕하십니까 강사님! 활용1편을 정독하고 jpa기본을 다지기위해 공부중인 학생입니다! 항상 좋은강의 해주셔서 정말 감사합니다 강사님 덕분에 공부하는게 즐겁습니다ㅎㅎ 임베디드 타입과 @MappedSuperclass중에 뭘써야할지 저도 궁금했었는데 다른분이 똑같은 질문을 올려서 그걸 보고 다른 궁금한점들이 있어서 여쭤보려합니다. 1. @MappedSuperclass는 공통적으로 많은 클래스에 공통항목을 적용할때 써야하고 임베디드 타입은 타입별로 사용될 메서드들이 나뉘어져야 할때 사용하면 되는건가요?!어느 경우에 어떤걸 쓸지 머리속에 딱 정리가 되었으면 하는데 두 경우가 많이 헷갈리는것 같습니다ㅜ2. 또한 자바에서는 다중 상속이 안되는데 MappedSuperclass로 상속을 써버리는게 괜찮은건지 궁금합니다!3. 활용1편에서 Address 설계를 임베디드로 하셨는데 MappedSuperclass를 안쓰신 이유가 궁금합니다! 4. 다른 답변의 댓글에서 결국에는 임베디드와 @MappedSuperclass는 상속과 위임의 차이밖에 없다고 하셨습니다! 그리고 JPQL 쿼리 때문에 상속을 선택하신다고 하셨는데 그러면 앞으로 메서드가 타입별로 나뉘어져야 할때 빼고 다 @MappedSuperclass만 써도 되는건지 궁급합니다! 막 궁금한걸 치다보니까 질문이 4개나 되었습니다ㅜ 혹시 질문이 많아서 답변하기에 불편하시다면 죄송합니다..
-
미해결자바 ORM 표준 JPA 프로그래밍 - 기본편
cascade = CascadeType.ALL질문
안녕하세요 게시판에서 게시글과 업로드의 관계에서 제 생각하고 다르게 잘 안먹혀서 질문드리겠습니다. Posts.java@OneToMany(mappedBy = "posts" , cascade = CascadeType.ALL)private List<Upload> uploadList = new ArrayList<Upload>(); Upload.java@ManyToOne@JoinColumn(name = "POSTS_ID")private Posts posts; 게시글하고 업로드의 관계는 업로드가 완전히 게시글에 종속되어서 게시글 올릴때 업로드도 다같이 되고 게시글 지우면 fk게시글no에 맞춰 업로드도 다 지우게 해서 잘되는데 문제는 수정할때 업로드를 따른거하다가 취소하면 기존꺼를 남겨야하니까 저는 지금 화면에서 업로드한거 삭제하면 화면에서만 안보이게 하고 수정하기 버튼을 누르면 기존꺼 업로드는 다 삭제하고 업로드를 다시하는식으로 하는데 문제는 서비스단에서 @Transactional public Long update(Long id, PostsUpdateRequestDto requestDto) { Posts posts = postsRepository.findById(id).orElseThrow(() -> new IllegalArgumentException("해당 게시글이 없습니다.id=" + id)); if(posts.getUploadList().size() > 0) { List<Upload> uploadList = posts.getUploadList(); for (Upload upload : uploadList) { Upload entity = uploadRepository.findById(upload.getId()).orElseThrow(()-> new IllegalArgumentException("해당 파일은 업습니다. id="+id)); uploadRepository.delete(entity); } } Posts entity = requestDto.toEntity(); posts.update(requestDto.getTitle(), requestDto.getContent(), entity.getUploadList()); return id;} uploadRepository.delete(entity); 삭제를해도 안먹히더라고요 CascadeType.ALL는 무조건 post가 지워질때만 upload도 지워지나요?
-
미해결자바 ORM 표준 JPA 프로그래밍 - 기본편
DDL 제약조건 명시여부
안녕하세요. 강의내용듣다가 궁금한 점이 생겨 질문드립니다^^ 예를들어, JPA의 DDL 자동생성 기능을 이용하지않고 flyway 같은 데이터베이스 migration 관리 툴로 스키마를 관리하는 상황에서, name컬럼이 unique 제약조건이 걸려있을때 실무에서는 해당 필드의 어노테이션으로 unique true나 길이제한 같은 제약을 보통 명시해주나요? 아니면 DDL 자동생성을 이용하지 않는상황에서는 딱히 명시해주지 않는 경우가 많나요?
-
미해결실전! 스프링 데이터 JPA
성능 테스트 질문
안녕하세요 영한님 강좌 잘 보고있습니다. 강좌중에 성능테스트에 대한 이야기를 많이 해주시는데, 혹시 성능 테스트는 어떤식으로 진행해야 할까요?!
-
해결됨실전! 스프링 부트와 JPA 활용1 - 웹 애플리케이션 개발
@Valid 유효성 체크 시 질문 있습니다!
강사님 안녕하세요! 상품 등록하는 부분에도 유효성 검사를 추가 해봤는데요. Neither BindingResult nor plain target object for bean name 오류가 나서 검색해보니 @ModelAttribute를 붙이면 된다고 해서 해결했습니다. 근데 회원등록 시에는 @ModelAttribute를 사용하지 않았어서 비교해봤더니, 모델객체에 담을 때 클래스명이랑 똑같이 설정하면 정상 동작하더라구요. 오류는 해결했는데 @ModelAttribute를 붙여야될 때도 있고 안 붙여도 될 때도 있고,,, 왜 이렇게 동작하는지 궁금합니다..ㅎㅎ 그리고 여기서 @ModelAttribute가 무슨 역할을 해주는지도 궁금합니다. model.addAttribute("form", new BookForm()); @Valid BookForm form => 오류남 model.addAttribute("form", new BookForm()); @ModelAttribute("form") @Valid BookForm form => 정상 동작 model.addAttribute("form", new BookForm()); @ModelAttribute @Valid BookForm form => 오류남 model.addAttribute("bookForm", new BookForm()); @Valid BookForm form => 정상 동작
-
해결됨스프링과 JPA 기반 웹 애플리케이션 개발
패키지 구조 관련 질문입니다.
안녕하세요. 어제 라이브 재밌었습니다.신세경.. 미국엔 잘 돌아가셨는지 궁금하네요..ㅎㅎ 다름이 아니고, 강의를 보고 개인 프로젝트를 진행하려고 하는데 패키지 구조를 도메인형으로 해야할지, 계층형으로 해야 할지에서 부터 고민이 되어 질문드립니다. 기선님 강의에서는 도메인으로 나뉘었고, 펫클리닉 프로젝트도 찾아보니 도메인으로 나눠놓았더라구요 제가 본 여타 다른 강의들에서는 컨트롤러/서비스/레포지토리/exception/ 등등으로 나눠놓은 걸 보아 어떤 것이 정답이다 라는 것은 없는것 같기도하고.. 해서 블로그 글을 참고해서 보니https://cheese10yun.github.io/spring-guide-directory/도메인이 더 낫다는 글을 보았습니다. 기선님 강의들에서는 더 나은 패키지구조 선택에 관해서 언급하셨던 기억이 없어서 질문드려요! 너무 좋은 강의 만들어주셔서 감사합니다. 많은 도움이 되고 있어요 :)
-
미해결자바 ORM 표준 JPA 프로그래밍 - 기본편
프록시 강의 중 초기화 실패 예제에 대한 질문
안녕하세요. 프록시 강의 중 em.close() 하게되면 영속성 컨텍스트가 닫혀서 프록시 초기화가 안된다는 에러가 나와야 하는데 결과가 정상동작하는데 이유를 알 수 있을까요? em.detach()할 경우는 정상 동작해 초기화 안된다는 메세지가 출력됩니다. 하이버네이트 버전이 올라가면서 기능을 지원하게 된 걸까요? 코드와 콘솔 결과는 아래와 같습니다. public class JpaMain { public static void main(String[] args) { EntityManagerFactory emf = Persistence.createEntityManagerFactory("hello"); EntityManager em = emf.createEntityManager(); EntityTransaction tx = em.getTransaction(); tx.begin(); try { Member member1 = new Member(); member1.setUsername("member1"); em.persist(member1); em.flush(); em.clear(); Member refMember = em.getReference(Member.class, member1.getId()); System.out.println(refMember.getClass());// em.detach(refMember); em.close(); refMember.getUsername(); System.out.println("-----------------------"); tx.commit(); } catch (Exception e) { tx.rollback(); e.printStackTrace(); } finally { em.close(); } emf.close(); } private static void printMemeber(Member member) { System.out.println(member.getUsername()); } private static void printMemberAndTeam(Member member) { String username = member.getUsername(); System.out.println(username); Team team = member.getTeam(); System.out.println(team.getName()); }}
-
미해결자바 ORM 표준 JPA 프로그래밍 - 기본편
UML, ERD 툴 질문
안녕하세요! JPA에 대해 원리를 이해하며 열심히 수강하고 있습니다. 프로젝트를 진행할 때 영한님 실전예제처럼 UML이나 ERD를 그린 후에 개발을 시작하려고 합니다. 여러가지 툴을 찾아봤는데 마음에 확 드는 툴이 없었습니다 ㅜ draw.io와 같은 툴도 사용해봤는데 설계 단계에서 수정이 많이 일어날 때 이걸 매번 직접 반영하는게 에너지가 많이 소요되더라구요. 영한님은 어떤 툴을 사용하시는 지 궁금합니다! 감사합니다.
-
미해결실전! 스프링 부트와 JPA 활용2 - API 개발과 성능 최적화
dto의 layer에대해 질문 드립니다.
dto는 Controller Layer에서 dto->Entity로 치환하여 Service레이어로 넘기는편이 맞을까요? Service Layer에서 dto->Entity로 치환하는것이 맞을까요? 제 개인적인 생각으로는 다양한 경로에서 모일 수 있는 request dto들을 전부 다 Service레이어에서 처리하는 것 보단 Controller단에서 치환하여 서비스는 엔티티로 비즈니스로직을 처리하는게 맞다고 생각하는데 영한님의 고견 부탁드리겠습니다.