묻고 답해요
164만명의 커뮤니티!! 함께 토론해봐요.
인프런 TOP Writers
-
미해결스프링 핵심 원리 - 기본편
isInstanceOf
안녕하세요!구글 검색을 해봐도 명확한 답을 찾기가 어려워 질문을 남깁니다.assertThat(bean).isInstanceOf(RateDiscountPolicy.class); 처럼 검증을 할 때isInstanceOf가 어떻게 동작을 하는건지 잘 모르겠습니다.assertThat(bean).isInstanceOf(DiscountPolicy.class); 해도 테스트 통과를 하더라구요 답변 부탁드립니다. 감사합니다.
-
미해결스프링 핵심 원리 - 기본편
스프링 내부의 컨테이너(?)
강의내용을 되짚어 보다가 문득 궁금증이 생겨 질문드립니다. 스프링 컨테이너를 직접 만들지 않아도 빈 객체들을 주입 받을 수 있는데, 스프링 내부에 컨테이너가 있는 걸까요? 내부에 컨테이너가 있는게 맞다면 어떤 종류의 컨테이너이며, 어떤 라이프 사이클을 가지고 동작하는 건가요? 공식 문서에도 컨테이너를 만들고 사용하는 것에대해서만 설명하고 내부에 컨테이너가 있다는 말은 찾지 못했는데, 이런 내용은 어떻게 확인 할 수 있을까요? 알려주신 것 같이 컨테이너(Config)를 직접 만들어 쓰는 경우가 많나요? 주로 어떤 상황에서 많이 쓰이나요? 감사합니다!
-
미해결스프링 MVC 1편 - 백엔드 웹 개발 핵심 기술
Accept vs Content-Type
안녕하십니까 강사님 강의를 듣던 도중에 미디어 타입 조건 매핑에서 Accept와 Content-Type이 헷갈려서 질문드립니다. (Http 강의를 듣고 정리한 것도 보고 왔습니다) Accept는 클라이언트가 선호하는 표현을 요청하는 것으로 클라이언트 입장에서 응답을 받을 때, Accept헤더에 있는 데이터 타입이 오지 않으면 내가 말한 데이터가 아니잖아라고 거절을 하는 것이고, Content-Type은 해당 헤더에 있는 데이터가 오지 않았을 경우 서버 입장에서 내가 처리할 수 있는 데이터가 아닌데? 라고 거절을 하는 건가요?? Accept가 요청 때만 사용한다고 알고있어서 헷갈리게 되어 질문드립니다 감사합니다
-
미해결스프링 입문 - 코드로 배우는 스프링 부트, 웹 MVC, DB 접근 기술
웹애플리케이션 계층구조가 mvc를 설명한건가요?
안녕하세요. 자바입문 듣고 스프링 강의를 신청하여 김영한님 강의를 듣는데요. 일반적인 웹애플리케이션 계층구조 설명하시는데 이것이 MVC 패턴 설명하신건지? 아니면 비슷한것인가 궁금합니다. 또한 클래스 의존관계 설명에서 구현체란 단어를 사용하시던데 구현체라는게 무엇인지??
-
미해결스프링 핵심 원리 - 기본편
빈 라이프 싸이클과 PostConstruct, PreConstruct 질문입니다.
1. 스프링빈은 객체를 생성한다.2. 의존관계 주입을 한다.3. 이후 필요한 데이터를 사용 할 수 있는 준비가 된다. 강의 듣다가 명확하게 이해하고 싶어서 질문드립니다. 의존관계 주입후 필요한 데이터를 사용 할 수 있는 준비가 된다고 하는데 그렇다면 생성자로 모든 데이터와 DB 커넥션을 해주는 작업을 한다면 의존관계주입이 발생될때 해당 초기화 했던 작업들은 다 무시가 되나요?
-
미해결실전! 스프링 부트와 JPA 활용1 - 웹 애플리케이션 개발
연관관계 편의 메서드 관련 Setter 사용
영한님께서 설명해주신 내용중 연관관계 편의메소드 등에서 Setter로 인한 문제점들은 알겠습니다. 이를 해결하기 위한 방법중 연관관계 편의 메소드에서 setXXX() 등을 사용하기 보단 별도의 메소드를 생성하여 changeMember()등으로 사용하는 것은 괜찮은지 궁금합니다. 예를들어 아래와 같이 작성시 문제가 될 소지가 있는지...궁금합니다. public void changeOrder(Order order) { this.order = order;} //===연관관계 편의 메서드 ===//public void addOrderItem(OrderItem orderItem) { this.orderItems.add(orderItem); orderItem.changeOrder(this);
-
미해결실전! 스프링 데이터 JPA
DTO안의 List가 있으면 어떻게 받아와야하나요..
만약 dto안에 list가 있으면 생성자는 어떤 식으로 만들어야 하고 jpql쿼리는 어떻게 찾아서 받아야하나요...???
-
미해결실전! 스프링 데이터 JPA
@Transaction 전파 관련 문의
안녕하세요 김영한 팀장님! 실습한 MemberRepository의 구현체로 SimpleJpaRepository가 생성되며, 내부의 findById 메서드가 @Transactional(readOnly)이 적용되어 있고 기본 설정이 "Propagation.REQUIRED"이기 때문에 부르는 쪽의 Transaction이 전파되는 것으로 이해했습니다. @Transactional@GetMapping("/tx/{id}")public void findMember3(@PathVariable("id") Long id) { Member member1 = memberRepository.findById(id).get(); Member member2 = capsule(id); System.out.println(member1); System.out.println(member2);}@Transactional(propagation = Propagation.REQUIRES_NEW)public Member capsule(Long id) { return memberRepository.findById(id).get();} 하지만 다음과 같이 컨트롤러 메서드 "findMember3"에 @Transactional을 걸고, memberRepository의 findById를 수정할 수 없으므로 capsule 메서드로 감싸서 member를 조회해봤는데요. propagation을 new로 설정했음에도 출력 결과가 같은 인스턴스를 가리키는 것으로 나왔습니다.select query도 하나만 발생했는데, 이 경우에도 같은 영속성 컨텍스트를 공유하게 되는 건가요?
-
미해결자바 ORM 표준 JPA 프로그래밍 - 기본편
Mybatis, JPA 혼용사용
안녕하세요 강의 잘 듣고 있습니다. 다름이 아니라, 기존 진행하던 프로젝트가 Spring, Mybatis를 사용하고 있어, JPA를 추가하여 혼용 사용하려고 합니다. 하나의 DB를 바라보게 하기 위해서 Datasource를 나눠서 생성하고, trancsaction을 Mybatis용 JPA용으로 나눠서 생성하였고, ChainedTransactionManager를 사용하여 트랜잭션을 묶어줬습니다. 하지만 계속 다음과 같은 에러가 발생하고 있습니다. [o.s.d.r.c.RepositoryConfigurationDelegate] - Multiple Spring Data modules found, entering strict repository configuration mode! 이런 문제가 발생했을때 어떻게 처리해야할까요 ㅜㅜㅜ 도움이 필요합니다. config.xml 파일입니다.. <?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:jpa="http://www.springframework.org/schema/data/jpa" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/tx http://www.springframework.org/schema/data/jpa http://www.springframework.org/schema/data/jpa/spring-jpa.xsd"> <bean id="propertyPlaceholderConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"> <property name="locations"> <value>classpath:mybatis/jdbc.properties</value> </property> </bean> <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"> <property name="driverClassName" value="${jdbc.driverClassName}"/> <property name="url" value="${jdbc.url}" /> <property name="username" value="${jdbc.username}" /> <property name="password" value="${jdbc.password}" /> <property name="maxWait" value="3000" /> <property name="poolPreparedStatements" value="true" /> <property name="maxOpenPreparedStatements" value="50" /> <!-- connection - validation query --> <property name="validationQuery" value="select 1"/> <property name="testWhileIdle" value="true" /> <property name="timeBetweenEvictionRunsMillis" value="7200000" /> </bean> <bean id="jpadataSource" class="org.apache.commons.dbcp.BasicDataSource"> <property name="driverClassName" value="${jdbc.driverClassName}"/> <property name="url" value="${jdbc.url}" /> <property name="username" value="${jdbc.username}" /> <property name="password" value="${jdbc.password}" /> <property name="maxWait" value="3000" /> <property name="poolPreparedStatements" value="true" /> <property name="maxOpenPreparedStatements" value="50" /> <!-- connection - validation query --> <property name="validationQuery" value="select 1"/> <property name="testWhileIdle" value="true" /> <property name="timeBetweenEvictionRunsMillis" value="7200000" /> </bean> <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"> <property name="dataSource" ref="dataSource" /> <property name="configLocation" value="classpath:mybatis/mybatis-config.xml" /> <property name="mapperLocations" value="classpath:mybatis/mapper/*.xml" /> </bean> <bean id="transactionManager" class="org.springframework.data.transaction.ChainedTransactionManager"> <constructor-arg> <list> <ref bean="mybatisTransactionManager"/> <ref bean="jpaTransactionManager"/> </list> </constructor-arg> </bean> <bean id="mybatisTransactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSource"></property> </bean> <bean id="jpaTransactionManager" class="org.springframework.orm.jpa.JpaTransactionManager"> <property name="entityManagerFactory" ref="jpaEntityManagerFactory" /> </bean> <bean id="jpaEntityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"> <property name="dataSource" ref="jpadataSource"></property> </bean> <tx:annotation-driven /> <aop:config proxy-target-class="true"> <aop:pointcut id="serviceOperation" expression="execution(* com.xii..*Service.*(..))" /> <aop:advisor id="transactionAdvisor" pointcut-ref="serviceOperation" advice-ref="txAdvice"/> </aop:config> <tx:advice id="txAdvice" transaction-manager="transactionManager"> <tx:attributes> <tx:method name="insert*" rollback-for="Exception"/> <tx:method name="save*" rollback-for="Exception"/> <tx:method name="update*" rollback-for="Exception"/> <tx:method name="delete*" rollback-for="Exception"/> </tx:attributes> </tx:advice> <bean id="sqlSession" class="org.mybatis.spring.SqlSessionTemplate"> <constructor-arg index="0" ref="sqlSessionFactory" /> </bean> <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer"> <property name="basePackage" value="com.xii" /> </bean> <jpa:repositories base-package="com.xii"/> </beans>
-
미해결실전! 스프링 부트와 JPA 활용1 - 웹 애플리케이션 개발
em.persist 관련 질문입니다.
[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (아니오)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예)[질문 내용]여기에 질문 내용을 남겨주세요. 안녕하세요 항상 수준 높은 강의에 감사드립니다. 몇 가지 의문점이 생겨서 질문하고자 작성하게 되었습니다. test에서 @Transactional 어노테이션이 롤백을 하신다고 강의에서 말씀하셨는데, 궁금한 점은 em.persist를 한 시점에서는 영속화 한 객체에 대해서 id 값은 영속성 컨텍스트에서 관리되면서 자동으로 부여되는건가요? db 에 isnert 하기 전부터 이미 id 값이 부여되서 관리되고 있는지 궁금합니다. 감사합니다.
-
해결됨실전! 스프링 부트와 JPA 활용1 - 웹 애플리케이션 개발
DAO와 REPOSITORY의 차이점...
안녕하세요 항상 좋은 강의 제공해주셔서 감사드립니다. 강의를 듣다보니 dao와 repository의 차이점이 궁금해서 질문을 남깁니다. 검색해보니 dao는 data persistence의 추상화 , repository는 collection of objects의 추상화라고 하는데, 사실상 둘의 기능은 비슷하다고 생각합니다. 하지만 둘의 차이를 명확하게 알고 싶어 질문드립니다. 혹시 mybatis를 사용할때 sql과 매핑할때 dao를 사용하고, repository는 엔티티를 영속성 컨텍스트에 영속화 시킬때 사용하는건가요???
-
미해결스프링 핵심 원리 - 기본편
getBeanDefinition
ApplicationContext말고 구체화된 클래스(예: AnnotationConfigApplicationContext)를 쓰는 이유가 getBeanDefinition을 쓸 수 없어서라고 하셨는데, 그 이유가 무엇인가요? AnnotationConfigApplicationContext가 구현한 여러가지 인터페이스중, ApplicationContext가 아닌 다른 인터페이스가 getBeanDefinition이라는 메서드를 제공하기 때문이라는 말씀이신가요?
-
미해결스프링 MVC 1편 - 백엔드 웹 개발 핵심 기술
HTTP API와 자바스크립트 질문
질문에 앞서 제가 자바스크립트를 잘 모르고 HTML, CSS만 대충 알고 있습니다. 참고하시고 답변 부탁드릴게요. (질문) HTTP API는 HTML이 아닌 데이터를 주고 받기 때문에 "웹 브라우저"가 아닌 "웹 클라이언트 자바스크립트"가 데이터를 처리하고 사용자에게 보여준다고 하셨습니다. 여기에서 웹 클라이언트 자바스크립트가 구체적으로 뭔지 모르겠습니다. 자바 스크립트라는 프로그램이 개인 PC마다 설치되어 있는 건지... 조금 더 구체적으로 설명해주시면 감사하겠습니다.
-
해결됨스프링 MVC 1편 - 백엔드 웹 개발 핵심 기술
CSR에 관해 질문드립니다.
안녕하세요. 항상 좋은 강의 감사드립니다. 제가 백엔드 쪽만 공부하다보니 프론트 쪽에 관해 많이 모르고 있는데요. 1. 강의에서 CSR에 대해서 설명해주신 부분에서 '서버'를 언급해주셨는데, 그 때의 서버는 리액트나 뷰와 같은 프론트단 서버를 의미하는 건가요? 그러면 CSR의 경우는 Spring 서버에 오기 전 클라이언트단 서버에서 이미 처리가 되고, 백단 서버에는 요청이 가지않는 상태를 의미하는건가요? 2. 전체적인 HTTP 흐름이 '클라이언트 -> 클라이언트단 서버 -> Spring 서버 -> DB -> 응답' 순이 맞을까요? 아니면 로직마다 다르게 적용되어 클라이언트 <-> 클라이언트단 서버, 클라이언트 <-> 백단 서버 이런식으로 요청, 응답을 받는건가요? 3. 그리고 제가 백엔드만 공부한 상태로 포트폴리오로 개인프로젝트를 혼자 개발해보려고 하는데요. 강의에서는 서버 사이드 렌더링 기술만 익히면 된다고 하셨는데, CSR 없이 타임리프와 spring으로만 개발해도 괜찮을까요? 백엔드 개발자가 개인프로젝트를 해야하는 할 때 갖춰야할 최소한의 프론트 지식이 궁금합니다.
-
미해결스프링 MVC 2편 - 백엔드 웹 개발 활용 기술
왜 log.error가아닌 log.info를 사용하나요?
error 메세지의 경우 log.error가 아닌가요?ㅜㅜ 실제 개발할때 이런 에러 로그에 대해서 info를 사용하는지 error혹은 warn을 사용하는지 궁금합니다.
-
미해결스프링 MVC 2편 - 백엔드 웹 개발 활용 기술
FileNotFoundException 오류
아래 코드를 작성하고 난 후 나는 에러입니다. 강의 내용상으로는 30:47에 작성하신 코드입니다. @ResponseBody@GetMapping("/images/{filename}")public Resource downloadImage(@PathVariable String filename) throws MalformedURLException { return new UrlResource("file:" + fileStore.getFullPath(filename));} 2021-09-23 14:12:09.196 ERROR 2112 --- [nio-8080-exec-5] o.a.c.c.C.[.[.[/].[dispatcherServlet] : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception java.io.FileNotFoundException: URL [file:C:/Users/계정이름/Desktop/study/${imageFile.getStoreFileName()}] cannot be resolved in the file system for checking its content length at org.springframework.core.io.AbstractFileResolvingResource.contentLength(AbstractFileResolvingResource.java:232) ~[spring-core-5.3.9.jar:5.3.9] at org.springframework.http.converter.ResourceHttpMessageConverter.getContentLength(ResourceHttpMessageConverter.java:121) ~[spring-web-5.3.9.jar:5.3.9] at org.springframework.http.converter.ResourceHttpMessageConverter.getContentLength(ResourceHttpMessageConverter.java:45) ~[spring-web-5.3.9.jar:5.3.9] at org.springframework.http.converter.AbstractHttpMessageConverter.addDefaultHeaders(AbstractHttpMessageConverter.java:260) ~[spring-web-5.3.9.jar:5.3.9] at org.springframework.http.converter.AbstractHttpMessageConverter.write(AbstractHttpMessageConverter.java:211) ~[spring-web-5.3.9.jar:5.3.9] at org.springframework.web.servlet.mvc.method.annotation.AbstractMessageConverterMethodProcessor.writeWithMessageConverters(AbstractMessageConverterMethodProcessor.java:293) ~[spring-webmvc-5.3.9.jar:5.3.9] at org.springframework.web.servlet.mvc.method.annotation.RequestResponseBodyMethodProcessor.handleReturnValue(RequestResponseBodyMethodProcessor.java:183) ~[spring-webmvc-5.3.9.jar:5.3.9] at org.springframework.web.method.support.HandlerMethodReturnValueHandlerComposite.handleReturnValue(HandlerMethodReturnValueHandlerComposite.java:78) ~[spring-web-5.3.9.jar:5.3.9] at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:124) ~[spring-webmvc-5.3.9.jar:5.3.9] at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:895) ~[spring-webmvc-5.3.9.jar:5.3.9] at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:808) ~[spring-webmvc-5.3.9.jar:5.3.9] at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87) ~[spring-webmvc-5.3.9.jar:5.3.9] at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1064) ~[spring-webmvc-5.3.9.jar:5.3.9] at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:963) ~[spring-webmvc-5.3.9.jar:5.3.9] at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006) ~[spring-webmvc-5.3.9.jar:5.3.9] at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:898) ~[spring-webmvc-5.3.9.jar:5.3.9] at javax.servlet.http.HttpServlet.service(HttpServlet.java:655) ~[tomcat-embed-core-9.0.52.jar:4.0.FR] at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883) ~[spring-webmvc-5.3.9.jar:5.3.9] at javax.servlet.http.HttpServlet.service(HttpServlet.java:764) ~[tomcat-embed-core-9.0.52.jar:4.0.FR] at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:227) ~[tomcat-embed-core-9.0.52.jar:9.0.52] at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) ~[tomcat-embed-core-9.0.52.jar:9.0.52] at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53) ~[tomcat-embed-websocket-9.0.52.jar:9.0.52] at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) ~[tomcat-embed-core-9.0.52.jar:9.0.52] at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) ~[tomcat-embed-core-9.0.52.jar:9.0.52] at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100) ~[spring-web-5.3.9.jar:5.3.9] at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) ~[spring-web-5.3.9.jar:5.3.9] at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) ~[tomcat-embed-core-9.0.52.jar:9.0.52] at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) ~[tomcat-embed-core-9.0.52.jar:9.0.52] at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93) ~[spring-web-5.3.9.jar:5.3.9] at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) ~[spring-web-5.3.9.jar:5.3.9] at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) ~[tomcat-embed-core-9.0.52.jar:9.0.52] at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) ~[tomcat-embed-core-9.0.52.jar:9.0.52] at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201) ~[spring-web-5.3.9.jar:5.3.9] at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) ~[spring-web-5.3.9.jar:5.3.9] at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) ~[tomcat-embed-core-9.0.52.jar:9.0.52] at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) ~[tomcat-embed-core-9.0.52.jar:9.0.52] at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:197) ~[tomcat-embed-core-9.0.52.jar:9.0.52] at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:97) ~[tomcat-embed-core-9.0.52.jar:9.0.52] at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:542) ~[tomcat-embed-core-9.0.52.jar:9.0.52] at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:135) ~[tomcat-embed-core-9.0.52.jar:9.0.52] at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92) ~[tomcat-embed-core-9.0.52.jar:9.0.52] at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:78) ~[tomcat-embed-core-9.0.52.jar:9.0.52] at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:357) ~[tomcat-embed-core-9.0.52.jar:9.0.52] at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:382) ~[tomcat-embed-core-9.0.52.jar:9.0.52] at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65) ~[tomcat-embed-core-9.0.52.jar:9.0.52] at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:893) ~[tomcat-embed-core-9.0.52.jar:9.0.52] at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1726) ~[tomcat-embed-core-9.0.52.jar:9.0.52] at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) ~[tomcat-embed-core-9.0.52.jar:9.0.52] at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1191) ~[tomcat-embed-core-9.0.52.jar:9.0.52] at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659) ~[tomcat-embed-core-9.0.52.jar:9.0.52] at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) ~[tomcat-embed-core-9.0.52.jar:9.0.52] at java.base/java.lang.Thread.run(Thread.java:834) ~[na:na] 이런 에러가 납니다. 제가 윈도우 환경이라서 경로를 잘못 설정했을까봐 https://www.inflearn.com/questions/268366 이곳을 참고하여 application.properties 파일을 logging.level.org.apache.coyote.http11=debug file.dir=C:/Users/계정이름/Desktop/study/ 이렇게 작성했는데, 제출 버튼을 누르면 저렇게 오류가 납니다. 위 코드를 주석처리하고 실행해보면 잘 실행이 되는데, 위 코드를 작성하고 실행시키면 저렇게 에러가 나네요. 왜그런지 알 수 있을까요?
-
미해결실전! 스프링 부트와 JPA 활용2 - API 개발과 성능 최적화
v1: 엔티티직접노출 방식에 달린 주석 질문
@GetMapping("/api/v1/orders")public List<Order> ordersV1() { List<Order> all = orderRepository.findAll(); for (Order order : all) { order.getMember().getName(); //Lazy 강제 초기화 order.getDelivery().getAddress(); //Lazy 강제 초기환 List<OrderItem> orderItems = order.getOrderItems(); orderItems.stream().forEach(o -> o.getItem().getName()); //Lazy 강제 초기화 } return all;} 첨부된 소스코드를 보면 "트랜잭션 안에서 지연 로딩 필요"라고 v1 메소드에 설명이 있습니다. orderRepository.findAll( ); 의 호출이후 트랜잭션은 종료됐을 텐데 그 이후에 강제 Lazy로딩을 하는 것이 위 주석의 설명과 혼동이 됩니다. 기본편에서 진행을 할 때는 항상 tx.commit( ) 이전에 Lazy로딩을 했기 때문에 트랜잭션 안에서 지연로딩을 한다는 의미를 당연하게 받아드렸지만 웹MVC를 결합하면서 Controller쪽에서 findAll() 호출 후 진행되는 상황은 트랜잭션이 종료된 후이기 때문입니다. 답변부탁드립니다. 감사합니다.
-
해결됨실전! 스프링 부트와 JPA 활용2 - API 개발과 성능 최적화
return new CreateMemberResponse(id); 필요성
@RestController @RequiredArgsConstructor public class MemberApiController { .. @PostMapping("/api/v1/members") public CreateMemberResponse saveMemberV1(@RequestBody @Valid Member member) { Long id = memberService.join(member); return new CreateMemberResponse(id); } @Data static class CreateMemberResponse { private Long id; public CreateMemberResponse(Long id) { this.id = id; } } 일 때, memberService.join(member); 의 반환 값이 엔티티가 아니고 단순히 Long id인 값인데도 return id; 로 안하고 CreateMemberResponse 클래스를 만들어 return new CreateMemberResponse(id); 로 하는 이유는 뭔가요 ? 처음에는 Long id = memberService.join(member); return id; 로 했다가 누군가가 inline으로 합쳐버려서 return memberService.join(member); 으로 만들어 버리면 memberService.join의 반환 값이 수정될 때 컴파일이 안뜨고, api에서 스펙이 바뀌어 오류가 생길 가능성이 있어서 컴파일 단계에서 막아버릴려고 CreateMemberResponse 클래스를 만들어 return new CreateMemberResponse(id); 를 해주는 것일까 생각도 들었는데, inline으로 합쳐버리고 memberService.join의 반환값이 바뀌어도 어차피 @PostMapping("/api/v1/members") public Long saveMemberV1(@RequestBody @Valid Member member) { Long id = memberService.join(member); return id; } 인 상태에서 inline하는 거니까 public Long saveMemberV1(..) {..} 에서 return값이 Long타입이 아니게 바뀌면 컴파일 뜰 것 같아서 그것도 아닌가 싶기도 하고 .. 유지보수할 때, 추적하기 쉬우려고 그러는 건가 싶기도 하고 .. 갑자기 든 생각인데, 일반적으로는 단순히 id만 반환할 일이 없으니 일반적인 케이스를 생각해 만드신 건가 싶기도 하고.. 이 케이스만 예외적으로 Long으로 써도 가능한 건지 궁금합니다 :]
-
미해결스프링 MVC 1편 - 백엔드 웹 개발 핵심 기술
FrontControllerServletV3의 기능중 이해가 안되는 부분이 있습니다.
Map<String, String> paramMap = createParamMap(request);ModelView mv = controller.process(paramMap);String viewName = mv.getViewName();MyView view = viewResolver(viewName);view.render(mv.getModel(), request, response); 안녕하세요 위 소스에 대한 내용이 궁금해서 문의 드립니다. 제가 이해한대로 우선 설명을 드리면.. Map<String, String> paramMap = createParamMap(request); request에서 받아온 값들을 Key, Value 형식으로 paramMap에 담아주는 역할을 함.(key: username, value : 34)이런식으로 ModelView mv = controller.process(paramMap); 주소값에 따라 value에 저장되어있는 컨트롤러(ex> MemberListControllerV3에서 저장한 viewName을 반환해준다(안에 값이 있으면 같이 보내준다(컨트롤러의 기능에 따라 저장된 값들) String viewName = mv.getViewName(); 이 부분이 위의 mv에 저장되어있던 값들중 viewName값(save-resultemd)을 가져온다. MyView view = viewResolver(viewName); 이곳에서 전체적인 경로(/WEB-INF/views/ + viewName + .jsp)를 조합해서 리턴할 풀 경로를 만들어준다. view.render(mv.getModel(), request, response); 이 부분이 제일 이해가 안가는 부분입니다. 모델에 있는 값들을 꺼내서 request에 담아서 jsp쪽으로 보내주는 내용인데.. render를 할 때 mv.getModel() 이 값에 모델 정보들을 넘겨주는데 getModel이라는 정보가 위에서 controller.process(paramMap)의 컨트롤러에서 process메소드를 실행해서 넣어준 mv.getModel().put() 값을 말하는게 맞는거죠? 그렇게 만들어준 값들을 view 화면에 넘겨주기 위해서 render를 할 때 mv.getModel정보를 같이 render에 넘겨줘서 render에서는 해당 값들을 뽑아서 request값에 setAttribute로 key, value로 넣어줘야 jsp 파일에서 쉽게 사용을 할 수 있기 때문에 render에서 request에 담아서 화면단으로 넘겨주는게 맞는거죠?? 정리가 안되는 부분이 있어서 문의글을 적으면서 차근차근 글을 적다보니 대략적으로 이런식으로 흘러가는거구나.. 하고 감이 잡히는 것 같은데 제가 이해하고 있는 부분이 맞는건지, 아니면 놓치는 부분이 있는지 궁금합니다.
-
미해결스프링 MVC 1편 - 백엔드 웹 개발 핵심 기술
init은 누가 호출하는 건가요..?
@RequestMapping("/basic/items") 여기로 url이 들어오면, get으로 바로 @GetMappingpublic String items(Model model) { 이쪽으로 들어오고, return으로 html을 반환하지 않나요? 그런데 상품이 등록 되어 있던데.. @PostConstructpublic void init() { itemRepository.save(new Item("testA", 10000, 10)); itemRepository.save(new Item("testB", 20000, 20));} 이 init은 누가 호출하는 것인지 궁금합니다.