Member 저장 ==========> public void save (Member member) { em .persist(member) ; } Item 저장 ==========> public void save (Item item) { if (item.getId() == null ) { em .persist(item) ; } else { em .merge(item) ; } } 위와 같이 Member/Item 저장 방식이 다른 이유가 있나요? 답변 부탁드립니다.
다른 엔티티들과 달리, 주문과 주문상품은 상태값 외에는 바뀔일이 없기 때문에 생성 메서드를 사용한게 맞는지 궁금합니다. (사실 이 부분도 의문입니다. 다른 엔티티들에도 유지보수를 위해 생성 메서드를 사용하는게 맞지 않을까 싶습니다.) 예제에서 주문과 주문상품에서도 @Setter를 사용하고 있기에 언제든 값이 변경될 수 있는 점 때문에 제가 생각한게 틀린건지 맞는건지 잘 모르겠습니다.
안녕하세요. 변경감지와 병합 챕터를 보고 질문드립니다. 말씀하신 내용중에 "merge 는 모든 필드를 업데이트하고, dirty check 는 변경된 부분만 업데이트하기때문에 dirty check 를 사용하는게 좋다" 라는 내용이 있는데요. 그래서 테스트를 좀 해봤는데 dirty check 로 update 쿼리가 날아가는 경우에도 모든 필드에 대한 update 쿼리가 날아가더라고요. 결국 실행되는 쿼리 자체는 merge 와 dirty check 가 동일한거같은데요. 그래서 제가 정리한건 "merge 보다 dirty check" 라기보다는 "기존 엔티티를 수정(update) 할때는 신규 객체를 만드는게 아니라 기존 엔티티를 찾아와서 하자" 인데, 이렇게 이해해도 될까요? + 조금 더 찾아보니까 하이버네이트에서 @DynamicUpdate 애노테이션을 지원하고있는데 이 애노테이션은 실무에서 적극적으로 사용하는지도 궁금합니다. 감사합니다.
안녕하세요 영한님! 강의 들으면서 개인적으로 작은 프로젝트를 하나 만들어 보고 있습니다. 다대다 관계 시 insert 방법이 궁금합니다. 아래와 같이 erd가 구성되어 있습니다. 회원 테이블, 상품 테이블 그리고 회원이 찜한상품 테이블 총 3개가 있고 찜한상품 테이블이 회원과 상품 테이블을 연결하는 연결테이블입니다. entity는 테이블과 같이 총 3개를 생성했습니다. (@ManyToMany는 사용하지 않고 비식별관계로 만들었습니다.) 1) UserRepository를 생성해서 User를 저장하고 2) ItemRepository를 생성해서 Item을 저장하고 3) ItemLikeRepository를 생성하고 ItemLike 객체를 생성 후 저장된 User와 Item의 연관관계를 설정하고 저장 이렇게 3단계를 거쳐서 모든 데이터를 저장하고 있는데요. 연결테이블의 저장소인 ItemLikeRepository를 생성해서 저장을 해야 될까..? 라는 의문점이 듭니다. ItemLikeRepository는 save() 외에는 거의 사용할 일이 없을거 같은데 구지 생성을 해야 될까 생각도 들고.. 다대다 관계 저장 시 효율적인 방법이 있을까요?? 감사합니다.
안녕하세요.항상 모든 질문에 정성스럽게 답변하시느라 고생이 많으십니다. 그래서 질문하는게 조심스럽지만 제가 못보는 부분이 있을가 걱정되 또 질문을 하게 되네요 ㅎㅎ 혹시 만약 이 강의에서 처럼 Category 가 계층 구조로 되어있으나 Item과 일대다 구조되어있을때 특정 category 하위에 카테고리에 속한 모든 item 을 찾을때 어떤방식으로 많이 구현하시나요? 제가 생각한 방법은 서비스 레이어에서 카테고리 리파지토리를 통해 특정 category엔티티를 찾아온다.loop를 돌면서 child를 모두 로딩시키 면서 child id 를 리스트로 만든다 -> 아이템 리파지토리의findByCategoryIds와같은 메서드로 해당 id에 속한 모든 item를 찾는다. 조금더 깔끔한 방법은 없을까요 ? 양방향 관계를 줄이는게 좋지만 이상황에서는 양방향 관계를 걸어서 Category에서 one to Many로 item을 가지고 있다가 그 리스트를 로딩후 반환하는게 나을까요? 항상 정말 좋은 강의와 꼼꼼한 답변 감사하게 생각하고 있습니다.
Failed to load ApplicationContext java.lang.IllegalStateException: Failed to load ApplicationContext at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:125) at org.springframework.test.context.support.DefaultTestContext.getApplicationContext(DefaultTestContext.java:108) at org.springframework.test.context.web.ServletTestExecutionListener.setUpRequestContextIfNecessary(ServletTestExecutionListener.java:190) at org.springframework.test.context.web.ServletTestExecutionListener.prepareTestInstance(ServletTestExecutionListener.java:132) at org.springframework.test.context.TestContextManager.prepareTestInstance(TestContextManager.java:246) at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.createTest(SpringJUnit4ClassRunner.java:227) at org.springframework.test.context.junit4.SpringJUnit4ClassRunner$1.runReflectiveCall(SpringJUnit4ClassRunner.java:289) at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12) at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.methodBlock(SpringJUnit4ClassRunner.java:291) at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:246) at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:97) at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290) at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71) at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288) at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58) at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268) at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61) at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70) at org.junit.runners.ParentRunner.run(ParentRunner.java:363) at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:190) at org.gradle.api.internal.tasks.testing.junit.JUnitTestClassExecutor.runTestClass(JUnitTestClassExecutor.java:110) at org.gradle.api.internal.tasks.testing.junit.JUnitTestClassExecutor.execute(JUnitTestClassExecutor.java:58) at org.gradle.api.internal.tasks.testing.junit.JUnitTestClassExecutor.execute(JUnitTestClassExecutor.java:38) at org.gradle.api.internal.tasks.testing.junit.AbstractJUnitTestClassProcessor.processTestClass(AbstractJUnitTestClassProcessor.java:62) at org.gradle.api.internal.tasks.testing.SuiteTestClassProcessor.processTestClass(SuiteTestClassProcessor.java:51) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:36) at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:24) at org.gradle.internal.dispatch.ContextClassLoaderDispatch.dispatch(ContextClassLoaderDispatch.java:33) at org.gradle.internal.dispatch.ProxyDispatchAdapter$DispatchingInvocationHandler.invoke(ProxyDispatchAdapter.java:94) at co m.sun.proxy.$Proxy2.processTestClass(Unknown Source) at org.gradle.api.internal.tasks.testing.worker.TestWorker.processTestClass(TestWorker.java:118) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:36) at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:24) at org.gradle.internal.remote.internal.hub.MessageHubBackedObjectConnection$DispatchWrapper.dispatch(MessageHubBackedObjectConnection.java:182) at org.gradle.internal.remote.internal.hub.MessageHubBackedObjectConnection$DispatchWrapper.dispatch(MessageHubBackedObjectConnection.java:164) at org.gradle.internal.remote.internal.hub.MessageHub$Handler.run(MessageHub.java:412) at org.gradle.internal.concurrent.ExecutorPolicy$CatchAndRecordFailures.onExecute(ExecutorPolicy.java:64) at org.gradle.internal.concurrent.ManagedExecutorImpl$1.run(ManagedExecutorImpl.java:48) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) at org.gradle.internal.concurrent.ThreadFactoryImpl$ManagedThreadRunnable.run(ThreadFactoryImpl.java:56) at java.lang.Thread.run(Thread.java:748) Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'entityManagerFactory' defined in class path resource [org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaConfiguration.class]: Invocation of init method failed; nested exception is org.hibernate.service.spi.ServiceException: Unable to create requested service [org.hibernate.engine.jdbc.env.spi.JdbcEnvironment] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1771) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:593) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:515) at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:320) at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:226) at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:318) at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:199) at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1105) at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:867) at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:549) at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:744) at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:391) at org.springframework.boot.SpringApplication.run(SpringApplication.java:312) at org.springframework.boot.test.context.SpringBootContextLoader.loadContext(SpringBootContextLoader.java:121) at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContextInternal(DefaultCacheAwareContextLoaderDelegate.java:99) at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:117) ... 49 more Caused by: org.hibernate.service.spi.ServiceException: Unable to create requested service [org.hibernate.engine.jdbc.env.spi.JdbcEnvironment] at org.hibernate.service.internal.AbstractServiceRegistryImpl.createService(AbstractServiceRegistryImpl.java:275) at org.hibernate.service.internal.AbstractServiceRegistryImpl.initializeService(AbstractServiceRegistryImpl.java:237) at org.hibernate.service.internal.AbstractServiceRegistryImpl.getService(AbstractServiceRegistryImpl.java:214) at org.hibernate.id.factory.internal.DefaultIdentifierGeneratorFactory.injectServices(DefaultIdentifierGeneratorFactory.java:152) at org.hibernate.service.internal.AbstractServiceRegistryImpl.injectDependencies(AbstractServiceRegistryImpl.java:286) at org.hibernate.service.internal.AbstractServiceRegistryImpl.initializeService(AbstractServiceRegistryImpl.java:243) at org.hibernate.service.internal.AbstractServiceRegistryImpl.getService(AbstractServiceRegistryImpl.java:214) at org.hibernate.boot.internal.InFlightMetadataCollectorImpl.<init>(InFlightMetadataCollectorImpl.java:179) at org.hibernate.boot.model.process.spi.MetadataBuildingProcess.complete(MetadataBuildingProcess.java:119) at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.metadata(EntityManagerFactoryBuilderImpl.java:1215) at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build(EntityManagerFactoryBuilderImpl.java:1246) at org.springframework.or m.jpa.vendor.SpringHibernateJpaPersistenceProvider.createContainerEntityManagerFactory(SpringHibernateJpaPersistenceProvider.java:58) at org.springframework.or m.jpa.LocalContainerEntityManagerFactoryBean.createNativeEntityManagerFactory(LocalContainerEntityManagerFactoryBean.java:365) at org.springframework.or m.jpa.AbstractEntityManagerFactoryBean.buildNativeEntityManagerFactory(AbstractEntityManagerFactoryBean.java:391) at org.springframework.or m.jpa.AbstractEntityManagerFactoryBean.afterPropertiesSet(AbstractEntityManagerFactoryBean.java:378) at org.springframework.or m.jpa.LocalContainerEntityManagerFactoryBean.afterPropertiesSet(LocalContainerEntityManagerFactoryBean.java:341) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1830) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1767) ... 64 more Caused by: org.hibernate.HibernateException: Access to DialectResolutionInfo cannot be null when 'hibernate.dialect' not set at org.hibernate.engine.jdbc.dialect.internal.DialectFactoryImpl.determineDialect(DialectFactoryImpl.java:100) at org.hibernate.engine.jdbc.dialect.internal.DialectFactoryImpl.buildDialect(DialectFactoryImpl.java:54) at org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator.initiateService(JdbcEnvironmentInitiator.java:137) at org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator.initiateService(JdbcEnvironmentInitiator.java:35) at org.hibernate.boot.registry.internal.StandardServiceRegistryImpl.initiateService(StandardServiceRegistryImpl.java:94) at org.hibernate.service.internal.AbstractServiceRegistryImpl.createService(AbstractServiceRegistryImpl.java:263) ... 81 more 강의 내용과 그대로 타이핑 했는데도 불구하고 이런 에러가 떳다면, H2 데이터베이스를 실행 해 보시고 다시 테스트를 진행 해 보세요 저의 경우 H2 데이터베이스를 실행 하고 테스트를 해보니 에러 없이 성공 했습니다.
안녕하세요 선생님 강의 잘 듣고있습니다. 이번 강의에는 포함되지 않은 내용인데 검색해도 뾰족한 방법이 없어서 부득이 질문 드립니다ㅠㅠ 플러터 생존코딩 책에서 Streambuilder와 Firebase를 이용하여 데이터를 실시간으로 받아서 앱에서 출력하는 부분을 작성하고있었습니다. 책에서 나오는 대로 Firebase와 연결을 하고 앱을 실행했는데 자꾸 아래와 같은 메시지가 나옵니다. W/Firestore(11071): (21.3.0) [OnlineStateTracker]: Could not reach Cloud Firestore backend. Connection failed 1 times. Most recent error: Status{code=PERMISSION_DENIED, description=The project was disabled or deleted., cause=null} W/Firestore(11071): This typically indicates that your device does not have a healthy Internet connection at the moment. The client will operate in offline mode until it is able to successfully connect to the backend. 그래서 혹시몰라서 코드에 snapshot에 데이터가 있을 경우 휴지통을 출력하게 했는데 시간이 좀 걸렸지만 휴지통이 나오더군요ㅠㅠ 집에서 하는거라 인터넷도 연결이 되어있고 이전에는 됐었는데 연습한다고 코드 다시 짰더니 이런 문제가 발생했습니다ㅜㅜ 답변 부탁드리겠습니다.ㅠㅠ
안녕하세요 제 이해가 짧아 어딘가 맥락을 놓친 것 같습니다만 그 부분을 스스로 찾기가 힘들어서 여쭤봅니다. @OneToMany(mappedBy = "order", cascade = cascadeType.ALL) private List<OrderItem> orderItems = new ArrayList<>(); 예시에 나온 위 소스를 보면 mappedBy가 걸린 곳에 (즉 연관관계의 주인이 아닌 쪽에) cascade가 걸려있습니다. 제가 이해하기론 mappedby는 읽기만 가능한데, cascade를 붙임으로써 arraylist에 들어있던 마치 업데이트도 가능해지는 것 같이 들려서 제가 헷갈리는 부분을 확인차 여쭤보고 싶습니다. mappedby가 쓰기도 가능해지는 건가요? 아니면 제가 어딘가 내용을 오해했나요?
완성된 백엔드랑 프론트 vue를 연결시키고 있습니다. db생성, 회원가입 까지는 정상적으로 작동합니다. 그런데 routes/user의 login의 passport. authenticate( 'local'~ 부분에서 Error: Unknown authentication strategy "local" 라는 에러가 발생합니다. passport/local 에 passport.use('local' ~)은 제대로 작성이 되어 있습니다!
안녕하세요 강사님 다름이 아니라 기존에 프로젝트에서 spring 프레임워크, jsp, 자바스크립트 + jquery 기반으로 실무에서 웹개발을 했는데 사실상 스프링을 사용하고 있다고 말하기 민망할 정도로 기능을 거의 사용하지 못했었습니다. 그래서 이부분도 새로 공부중입니다ㅠㅠ 강의를 듣다보니 @Vaild나 NotEmpty같은 어노테이션도 알게 되고 BindingResult 같은 클래스 패키지도 알게되면서 뭔가 새로태어나는 기분이 들고 있습니다. 이번 강의 끝에 유효성 검사부분을 배우면서 생각이 드는 것이 저는 보통 유효성 검사를 할 때 자바스크립트 jquery를 사용해서 클라이언트단에서 유효성 검사를 하고 중요한 데이터의 경우 백단에서 DB체크(?)를 한번 더 해주는 식으로 개발했었는데요 스프링+타임리프를 조합하니 클라이언트단에서도 UX조작이 가능한 것 같았습니다. 유효성 검사의 어노테이션들을 적절하게 사용한다면 더이상 클라이언트단에서 자바스크립트를 통해 유효성 검사 부분이 불필요하게 되는 건가 조심스럽게 여쭤봅니다.
안녕하세요. 예제에서 MemberForm에서 Member 엔티티를 생성할때 컨트롤러에서 생성코드를 작성하셨는데요. Member 엔티티를 생성하는걸 MemberForm 에서 처리하는거에 대해서는 어떻게 생각하시나요? (ex. memberForm.toMember()) 예제가 아닌 실무에서 평소 영한님께서는 어떻게 하시는지, 어떻게 생각하시는지 궁금해서 여쭤봅니다!
안녕하세요. 복습을 하다 궁금한 점이 생겨 질문을 남깁니다. 영한님 소스에서 양방향인 경우 cascade 옵션을 사용한 부분이 있는데, 한번은 주인인쪽에, 또 다른 한번은 mappedBy쪽에 사용했습니다. 1. casecade 옵션은 어느쪽에 다는게 좋은건지 궁금합니다. 2. 만약 양쪽 다 달아도 상관 없는건 지도 궁금합니다. 실무에서 사용법을 몰라 양쪽에 달아두었는데, 문제가 있을거 같아 걱정이 되네요 ㅠㅠ 감사합니다~
제가 도메인, 서비스, 레포지토리 같은것들을 자바를 공부하며 처음 알게되었는데요 도메인이라고 하면 계속 www 같은 도메인이 떠오르네요 domain: 엔티티객체의 모음 service: 비즈니스로직 repository: 엔티티객체를 활용한 jpa코드사용 이렇게 생각하면 될까요?? 그리고 웹어플리케이션을 만들때 만들기 나름이겠지만, 쿠키나 세션을 사용해서 로그인처리를 하는지 jwt를 사용하시나요?? 대부분의 웹서비스는 jwt필요없이 쿠키만으로 충분하다는 어느 유튜버분의 의견도 있던데 어떻게 생각하시는지 궁금합니다!
안녕하세요. 올려주신 강의 잘 듣던 중 궁금한 점이 생겨 질문드립니다. @Transactional을 테스트 케이스에서 쓸 경우에는 커밋이 안되고 롤백 을 한다고 하셨는데, MemberServiceTest에서 만든 2개의 테스트 중 중복_회원_예외() 메서드 실행 시에는 아래 로그에 INSERT쿼리가 나와서요 ... 회원가입() 메서드 테스트 시에는 INSERT쿼리가 로그에 찍히지 않는데 중복_회원_예외() 메서드에는 INSERT쿼리가 찍히는 이유가 궁금합니다.
안녕하세요. 강의 잘 듣고 있던 도중 궁금한 점이 생겨서 질문드립니다. 엔티티 설계시 주의점 21분 쯤에 cascade옵션 에 대해서 설명해 주셨는데, 왜 Order 엔티티에 있는 필드값에만 이를 적용하고 다른 곳에는 적용하지 않으셨는지 궁금합니다. 또한, 어떤 기준을 통해 cascade 옵션을 적용시켜야 하는지 궁금해서 여쭤봅니다.
public static OrderItem createOrderItem(...){ // ... } 1. 제목과 동일합니다. 저 같은 경우엔 @Builder를 사용하긴 하는데 빌더패턴보다 더 선호되는 방식인가요? 2. 또한 생성자명을 따로 정하는 이유가 있을까요? 뭔가 의도는 알 거 같기도 한데, 제 추측 말고 정확한 이유가 궁금합니다.