질문드립니다.
미해결
타입스크립트의 모든 것
클래스 - readonly 와 생성자 이 수업에서 타임라인 28초쯤부터 ~ 1분 13초쯤까지 어떨 때는 정보를 보낼 때 class를 쓰고 어떨 때는 json과 object를 쓴다고 예를 들어주시는 내용 같은데.. 말이 좀 엉켜서 제가 이해가 잘 안되네요 😥 다시 한번 설명 좀 부탁드려도 될까요?
- typescript
- nestjs
172만명의 커뮤니티!! 함께 토론해봐요.
미해결
타입스크립트의 모든 것
클래스 - readonly 와 생성자 이 수업에서 타임라인 28초쯤부터 ~ 1분 13초쯤까지 어떨 때는 정보를 보낼 때 class를 쓰고 어떨 때는 json과 object를 쓴다고 예를 들어주시는 내용 같은데.. 말이 좀 엉켜서 제가 이해가 잘 안되네요 😥 다시 한번 설명 좀 부탁드려도 될까요?
해결됨
[코드캠프] 부트캠프에서 만든 고농축 백엔드 코스
import { Injectable } from '@nestjs/common'; import { InjectRepository } from '@nestjs/typeorm'; import { Repository } from 'typeorm/repository/Repository'; import { User } from '../users/entities/user.entity'; import { Payment, POINT_TRANSACTION_STATUS_ENUM, } from './entities/payment.entity'; @Injectable() export class PaymentService { constructor( @InjectRepository(Payment) private readonly paymentRepository: Repository<Payment>, @InjectRepository(User) private readonly userRepository: Repository<User>, ) {} async create({ impUid, amount, currentUser }) { const pointTransaction = await this.paymentRepository.create({ impUid, amount, user: currentUser, status: POINT_TRANSACTION_STATUS_ENUM.PAYMENT, }); await this.paymentRepository.save(pointTransaction); const user = await this.userRepository.findOne({ id: currentUser.id }); console.log(amount); await this.userRepository.update( { id: user.id }, // where { point: user.point + amount }, ); return pointTransaction; } } payment 과제 중 payment.service.ts 코드입니다. 결제는 문제없이 처리가 되었고, payment 테이블에 거래기록이 저장되어야 하는데 이러한 에러가 발생합니다. [Nest] 288 - 03/29/2023, 7:34:01 AM ERROR [ExceptionsHandler] Cannot perform update query because update values are not defined. Call "qb.set(...)" method to specify updated values. 여러 시도를 해봤지만 해결되지 않아 커뮤니티에 글 남깁니다!
미해결
Node.js의 모든 것
현재 공식 레퍼런스를 보며 prisma, next를 사용해서 게시판을 만드는 프로젝트 작업을 성공적으로 끝냈지만 한가지 문제가 있었습니다. prisma의 now()가 timezone UTC를 베이스로 작동하고 있는데 이걸 설정하는 방법을 prisma에서 공식적으로 지원하지 않는다고 검색을 통해 알게되었습니다. 아직 강의 내용을 수강하지는 않았기에 강의내용에서 timezone 관련 이슈를 다루는지는 모르겠지만 그 파트를 직접 찾기에는 오래 걸리는터라.... 먼저 질문부터 남겨봅니다.
해결됨
실전! 스프링 부트와 JPA 활용2 - API 개발과 성능 최적화
강의를 중간에 distinct를 적용하지 않으면 포스트맨에서 결과가 중복되게 나오고, 쿼리도 inner join으로 되어야 하는데 이상합니다ㅜ 코드가 모두 동일한데, 콘솔에 찍어봐도 4건이 아닌 2건 밖에 조회가 되지 않고 결과도 2건으로 나옵니다.. 또한, 강의에서는 inner join이 나가는데 제 코드는 join이 나갑니다..뭐가 문제일까요?
미해결
실전! 스프링 부트와 JPA 활용1 - 웹 애플리케이션 개발
https://drive.google.com/file/d/1OKpCQpwYWvWjppEIcvzWpSZKy09GAivy/view?usp=sharing 위에는 구글 압축 파일입니다. 다음은 에러 내용입니다. Caused by: org.attoparser.ParseException: Exception evaluating SpringEL expression: "item.orderItems[0]. item.name " (template: "order/orderList" - line 46, col 21) Caused by: org.springframework.expression.spel.SpelEvaluationException: EL1025E: The collection has '0' elements, index '0' is invalid 야생형 코스로 들으려고 하다보니 에러난 부분을 고치기가 어렵고 다른 분들도 같은 질문을 많이 하셨어서, 질문들도 다 확인해보고 저의 코드에서도 해당 부분들을 유심히 보았으나 에러를 잡지 못해서 질문드렸습니다. 위의 에러코드 내용을 미루어보아 orderItems의 값이 null이어서 화면에 나오지 않는다고 생각하여서 그 부분을 확인해보았는데, null로 출력되는 것은 확인하였습니다. html코드의 문제인가 싶어 코드도 계속 확인해보고, 선생님께서 제공해주신 코드파일에 있는 html을 그대로 복사해서 실행해보았는데도 수정이 되지 않아서 질문드렸습니다. 감사합니다. Whitelabel Error Page This application has no explicit mapping for /error, so you are seeing this as a fallback. Tue Mar 28 19:44:33 KST 2023 There was an unexpected error (type=Internal Server Error, status=500). An error happened during template parsing (template: "class path resource [templates/order/orderList.html]") org.thymeleaf.exceptions.TemplateInputException: An error happened during template parsing (template: "class path resource [templates/order/orderList.html]") at org.thymeleaf.templateparser.markup.AbstractMarkupTemplateParser.parse( AbstractMarkupTemplateParser.java:241 ) at org.thymeleaf.templateparser.markup.AbstractMarkupTemplateParser.parseStandalone( AbstractMarkupTemplateParser.java:100 ) at org.thymeleaf.engine.TemplateManager.parseAndProcess( TemplateManager.java:666 ) at org.thymeleaf.TemplateEngine.process( TemplateEngine.java:1103 ) at org.thymeleaf.TemplateEngine.process( TemplateEngine.java:1077 ) at org.thymeleaf.spring6.view.ThymeleafView.renderFragment( ThymeleafView.java:372 ) at org.thymeleaf.spring6.view.ThymeleafView.render( ThymeleafView.java:192 ) at org.springframework.web.servlet.DispatcherServlet.render( DispatcherServlet.java:1415 ) at org.springframework.web.servlet.DispatcherServlet.processDispatchResult( DispatcherServlet.java:1159 ) at org.springframework.web.servlet.DispatcherServlet.doDispatch( DispatcherServlet.java:1098 ) at org.springframework.web.servlet.DispatcherServlet.doService( DispatcherServlet.java:974 ) at org.springframework.web.servlet.FrameworkServlet.processRequest( FrameworkServlet.java:1011 ) at org.springframework.web.servlet.FrameworkServlet.doGet( FrameworkServlet.java:903 ) at jakarta.servlet.http.HttpServlet.service( HttpServlet.java:537 ) at org.springframework.web.servlet.FrameworkServlet.service( FrameworkServlet.java:885 ) at jakarta.servlet.http.HttpServlet.service( HttpServlet.java:631 ) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter( ApplicationFilterChain.java:205 ) at org.apache.catalina.core.ApplicationFilterChain.doFilter( ApplicationFilterChain.java:149 ) at org.apache.tomcat.websocket.server.WsFilter.doFilter( WsFilter.java:53 ) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter( ApplicationFilterChain.java:174 ) at org.apache.catalina.core.ApplicationFilterChain.doFilter( ApplicationFilterChain.java:149 ) at org.springframework.web.filter.RequestContextFilter.doFilterInternal( RequestContextFilter.java:100 ) at org.springframework.web.filter.OncePerRequestFilter.doFilter( OncePerRequestFilter.java:116 ) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter( ApplicationFilterChain.java:174 ) at org.apache.catalina.core.ApplicationFilterChain.doFilter( ApplicationFilterChain.java:149 ) at org.springframework.web.filter.FormContentFilter.doFilterInternal( FormContentFilter.java:93 ) at org.springframework.web.filter.OncePerRequestFilter.doFilter( OncePerRequestFilter.java:116 ) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter( ApplicationFilterChain.java:174 ) at org.apache.catalina.core.ApplicationFilterChain.doFilter( ApplicationFilterChain.java:149 ) at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal( CharacterEncodingFilter.java:201 ) at org.springframework.web.filter.OncePerRequestFilter.doFilter( OncePerRequestFilter.java:116 ) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter( ApplicationFilterChain.java:174 ) at org.apache.catalina.core.ApplicationFilterChain.doFilter( ApplicationFilterChain.java:149 ) at org.apache.catalina.core.StandardWrapperValve.invoke( StandardWrapperValve.java:166 ) at org.apache.catalina.core.StandardContextValve.invoke( StandardContextValve.java:90 ) at org.apache.catalina.authenticator.AuthenticatorBase.invoke( AuthenticatorBase.java:493 ) at org.apache.catalina.core.StandardHostValve.invoke( StandardHostValve.java:115 ) at org.apache.catalina.valves.ErrorReportValve.invoke( ErrorReportValve.java:93 ) at org.apache.catalina.core.StandardEngineValve.invoke( StandardEngineValve.java:74 ) at org.apache.catalina.connector.CoyoteAdapter.service( CoyoteAdapter.java:341 ) at org.apache.coyote.http11.Http11Processor.service( Http11Processor.java:390 ) at org.apache.coyote.AbstractProcessorLight.process( AbstractProcessorLight.java:63 ) at org.apache.coyote.AbstractProtocol$ConnectionHandler.process( AbstractProtocol.java:894 ) at org.apache.tomcat.util.net .NioEndpoint$SocketProcessor.doRun( NioEndpoint.java:1741 ) at org.apache.tomcat.util.net.SocketProcessorBase.run ( SocketProcessorBase.java:52 ) at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker( ThreadPoolExecutor.java:1191 ) at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run( ThreadPoolExecutor.java:659 ) at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run( TaskThread.java:61 ) at java.base/java.lang.Thread.run( Thread.java:833 ) Caused by: org.attoparser.ParseException: Exception evaluating SpringEL expression: "item.orderItems[0]. item.name " (template: "order/orderList" - line 46, col 21) at org.attoparser.MarkupParser.parseDocument( MarkupParser.java:393 ) at org.attoparser.MarkupParser.parse( MarkupParser.java:257 ) at org.thymeleaf.templateparser.markup.AbstractMarkupTemplateParser.parse( AbstractMarkupTemplateParser.java:230 ) ... 48 more Caused by: org.thymeleaf.exceptions.TemplateProcessingException: Exception evaluating SpringEL expression: "item.orderItems[0]. item.name " (template: "order/orderList" - line 46, col 21) at org.thymeleaf.spring6.expression.SPELVariableExpressionEvaluator.evaluate( SPELVariableExpressionEvaluator.java:292 ) at org.thymeleaf.standard.expression.VariableExpression.executeVariableExpression( VariableExpression.java:166 ) at org.thymeleaf.standard.expression.SimpleExpression.executeSimple( SimpleExpression.java:66 ) at org.thymeleaf.standard.expression.Expression.execute( Expression.java:109 ) at org.thymeleaf.standard.expression.Expression.execute( Expression.java:138 ) at org.thymeleaf.standard.processor.AbstractStandardExpressionAttributeTagProcessor.doProcess( AbstractStandardExpressionAttributeTagProcessor.java:144 ) at org.thymeleaf.processor.element.AbstractAttributeTagProcessor.doProcess( AbstractAttributeTagProcessor.java:74 ) at org.thymeleaf.processor.element.AbstractElementTagProcessor.process( AbstractElementTagProcessor.java:95 ) at org.thymeleaf.util.ProcessorConfigurationUtils$ElementTagProcessorWrapper.process( ProcessorConfigurationUtils.java:633 ) at org.thymeleaf.engine.ProcessorTemplateHandler.handleOpenElement( ProcessorTemplateHandler.java:1314 ) at org.thymeleaf.engine.OpenElementTag.beHandled( OpenElementTag.java:205 ) at org.thymeleaf.engine.Model.process( Model.java:282 ) at org.thymeleaf.engine.Model.process( Model.java:290 ) at org.thymeleaf.engine.IteratedGatheringModelProcessable.processIterationModel( IteratedGatheringModelProcessable.java:368 ) at org.thymeleaf.engine.IteratedGatheringModelProcessable.process( IteratedGatheringModelProcessable.java:222 ) at org.thymeleaf.engine.ProcessorTemplateHandler.handleCloseElement( ProcessorTemplateHandler.java:1640 ) at org.thymeleaf.engine.TemplateHandlerAdapterMarkupHandler.handleCloseElementEnd( TemplateHandlerAdapterMarkupHandler.java:388 ) at org.thymeleaf.templateparser.markup.InlinedOutputExpressionMarkupHandler$InlineMarkupAdapterPreProcessorHandler.handleCloseElementEnd( InlinedOutputExpressionMarkupHandler.java:322 ) at org.thymeleaf.standard.inline.OutputExpressionInlinePreProcessorHandler.handleCloseElementEnd( OutputExpressionInlinePreProcessorHandler.java:220 ) at org.thymeleaf.templateparser.markup.InlinedOutputExpressionMarkupHandler.handleCloseElementEnd( InlinedOutputExpressionMarkupHandler.java:164 ) at org.attoparser.HtmlElement.handleCloseElementEnd( HtmlElement.java:169 ) at org.attoparser.HtmlMarkupHandler.handleCloseElementEnd( HtmlMarkupHandler.java:412 ) at org.attoparser.MarkupEventProcessorHandler.handleCloseElementEnd( MarkupEventProcessorHandler.java:473 ) at org.attoparser.ParsingElementMarkupUtil.parseCloseElement( ParsingElementMarkupUtil.java:201 ) at org.attoparser.MarkupParser.parseBuffer( MarkupParser.java:725 ) at org.attoparser.MarkupParser.parseDocument( MarkupParser.java:301 ) ... 50 more Caused by: org.springframework.expression.spel.SpelEvaluationException: EL1025E: The collection has '0' elements, index '0' is invalid at org.springframework.expression.spel.ast.Indexer$CollectionIndexingValueRef.growCollectionIfNecessary( Indexer.java:700 ) at org.springframework.expression.spel.ast.Indexer$CollectionIndexingValueRef.getValue( Indexer.java:664 ) at org.springframework.expression.spel.ast.Indexer.getValueInternal( Indexer.java:102 ) at org.springframework.expression.spel.ast.CompoundExpression.getValueRef( CompoundExpression.java:61 ) at org.springframework.expression.spel.ast.CompoundExpression.getValueInternal( CompoundExpression.java:91 ) at org.springframework.expression.spel.ast.SpelNodeImpl.getValue( SpelNodeImpl.java:112 ) at org.springframework.expression.spel.standard.SpelExpression.getValue( SpelExpression.java:338 ) at org.thymeleaf.spring6.expression.SPELVariableExpressionEvaluator.evaluate( SPELVariableExpressionEvaluator.java:265 ) ... 75 more
미해결
스프링 입문 - 코드로 배우는 스프링 부트, 웹 MVC, DB 접근 기술
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요. 1. 강의 내용과 관련된 질문을 남겨주세요. 2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요. (자주 하는 질문 링크: https://bit.ly/3fX6ygx) 3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요. (질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG) 질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요. ========================================= [질문 템플릿] 1. 강의 내용과 관련된 질문인가요? (예/아니오) 2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오) 3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오) [질문 내용] 여기에 질문 내용을 남겨주세요. home.html 에 <a href="/members/new">회원 가입</a> 여기서 /members/new 가 localhost:8080/members/new 로 연결이 되는 것 같은 데 어떻게 가능한건지 잘 모르겠습니다. /members/new 는 절대경로로 알고 있는데 프로젝트 폴더에는 이러한 폴더가 없습니다.
미해결
Slack 클론 코딩[백엔드 with NestJS + TypeORM]
수업에서는 기존 DB라 typeorm-model-generator를 사용했는데요, 저의 질문의 요점은 ORM으로 DML 위주의 사용이 보편적인가 하는 것입니다. 제가 python하다가 node.js로 넘어와서, python 예를 들어 죄송합니다만, https://velog.io/@youngkiu/SQLAlchemy-with-DDL python에서는 model도 create table sql로 만들지 않고, model을 생성하고, ORM에서 DDL 처리도 같이 해주었습니다. 스프링에서도 DDL은 ORM을 사용하지 않고, DB에서 직접 처리한다는 이야기를 듣기도 하여, 업계에서 ORM의 일반적인 사용방법이 궁금하여 질문드립니다. 늘 많이 배우고 있습니다. 감사합니다. 타입스크립트 책 얼릉 출간해 주세요. 바로 구매하겠습니다.
해결됨
실전! 스프링 부트와 JPA 활용1 - 웹 애플리케이션 개발
안녕하세요 선생님!! 항상 좋은 강의 해주셔서 감사드립니다 :) 강의에서 new 생성자를 못쓰도록 생성자를PROTECTED로 막으시고 생성 메서드만 사용하도록 하셨는데요. 프로젝트를 진행할 경우나 실무에서 생성 메서드만 통일해서 사용하는 것이 좋을까요 아님 아래 예시와 같이 생성 메서드와 빌더 패턴 둘 다 혼합해서 사용해도 괜찮을까요? Order 클래스의 생성 메서드에서 Setter를 안쓰고 예시와 같이 생성자를 사용해도 괜찮을까요? 감사합니다! Item @Builder private Item(String name, int price, int stockQuantity) { this.name = name; this.price = price; this.stockQuantity = stockQuantity; } Order private Order(OrderStatus status, Member member) { this.status = status; this.member = member; this.orderDate = LocalDateTime.now(); } public static Order createOrder(OrderStatus status, Member member, OrderItem... orderItems) { Order order = new Order(status, member); for (OrderItem orderItem : orderItems) { order.addOrderItem(orderItem); } return order; }
해결됨
[코드캠프] 부트캠프에서 만든 고농축 백엔드 코스
console.log("안녕하세요, 문자 인증번호 보내드립니다.") function createTokenOfPhone(myphone){ if(myphone.length !== 10 && myphone.length !== 11){ console.log("에러 발생! 핸드폰 번호를 제대로 입력해 주세요. ") return } const aaaa=6 if(aaaa === undefined){ console.log("에러 발생!!! 갯수를 제대로 입력해 주세요!!!") return } else if(aaaa <= 0){ console.log("에러 발생!! 갯수가 너무 적습니다!!") return }else if(aaaa > 10){ console.log("에러 발생!!! 갯수가 너무 많습니다!!!") return } const result = String(Math.floor(Math.random() * 10 ** aaaa)).padStart(aaaa,"0") console.log(result) console.log(myphone+ "번호로 인증번호" +result+ "를 전송합니다!!!") createTokenOfPhone("01012341234") 수업과 동일하게 코드를 작성했으나 아래와 같은 에러가 뜹니다. (base) c@Dui-c-G9C7V6620L 01-01-token % node index.js /Users/c/Desktop/codecamp-backend-03./class/01-01-token/index.js:25 createTokenOfPhone("01012341234") SyntaxError: Unexpected end of input at internalCompileFunction (node:internal/vm:73:18) at wrapSafe (node:internal/modules/cjs/loader:1176:20) at Module._compile (node:internal/modules/cjs/loader:1218:27) at Module._extensions..js (node:internal/modules/cjs/loader:1308:10) at Module.load (node:internal/modules/cjs/loader:1117:32) at Module._load (node:internal/modules/cjs/loader:958:12) at Function.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:81:12) at node:internal/main/run_main_module:23:47
미해결
탄탄한 백엔드 NestJS, 기초부터 심화까지
안녕하세요. 상석님! 상석님의 강의를 듣고 공식문서와 typeorm, mongoose등의 공식문서를 함께 이용하여 nest 프로젝트를 제작중인 1년차 node js 개발자입니다. 강의 너무 잘 들었습니다. 개인적으로 프로젝트를 진행하는 중 dto파일과 entity를 어떻게 관리하면 수월할까 라는 고민을 깊게 하게 되었습니다. chat gpt나 스택오버 플로우, 구글 등 많은 검색을 해봤지만 제 실력이 부족한지 정보를 찾기가 힘들어 여쭤보게 되었습니다. export class CreateRequestPostDto { @ApiProperty({ example: 'youtube uri', name: 'youtubeUri' }) @IsUrl() uri: string; @ApiProperty({ example: 'postTitle writed for user' }) @IsString() postTitle: string; @ApiProperty({ example: 'postDescription writed for user' }) @IsString() postDescription: string; } export class UpdatePostDto { @ApiProperty({ example: 'postTitle writed for user' }) @IsString() postTitle: string; @ApiProperty({ example: 'postDescription writed for user' }) @IsString() postDescription: string; } 위는 제가 만들고 있는 프로젝트의 일부입니다. postTitle과 postDescription이 두 클래스에서 중복이 되는 케이스인데 상속을 이용해서 postTitle과 postDescription을 따로 빼는 방법은 제가 원하는 방향이 아닙니다. 저는 기본적인 base dto클래스를 하나 만들어 놓고 이를 재활용하는 방법을 사용하고 싶습니다. export class BasePostClass { @ApiProperty({ example: 'youtube uri', name: 'youtubeUri' }) @IsUrl() uri: string; @ApiProperty({ example: 'postTitle writed for user' }) @IsString() postTitle: string; @ApiProperty({ example: 'postDescription writed for user' }) @IsString() postDescription: string; } 만약 위와 같은 클래스가 있다면 이를 이용해서 export class uriPostClass { uri: 위의 BasePostClass에 있는 uri 프로퍼티만을 가져와서 이 곳에서 사용하고 싶습니다. } 이와 같이 @ApiProperty 데코레이터를 다시 적어주지 않아도 되고 BasePostClass의 프로퍼티 하나를 바꾸면 이 클래스를 이용해 다른 클래스들에 영향을 주고싶은겁니다. uri라는 이름을 URI로 변경하면 이 다른 클래스에서도 영향을 받아 URI로 변한다거나 하다못해 서버 실행 과정에서 에러라도 발생시킬 수 있도록 하고싶습니다. 프로젝트가 커지다보니 DTO파일을 관리하기도 쉽지 않았어요. db의 컬럼 이름을 하나 바꿔주면 여기저기 dto파일을 찾아다니며 같이 바꿔줘야 했습니다. 좋은 방법이 있다면 알려주실 수 있을까요?
해결됨
[코드캠프] 부트캠프에서 만든 고농축 백엔드 코스
https://practice.codebootcamp.co.kr/graphql 는 사용을 못하는데 그럼 과제 연습은 못하나요?
해결됨
실전! 스프링 데이터 JPA
[질문 템플릿] 1. 강의 내용과 관련된 질문인가요? (예) 2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예) 3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예) [질문 내용] 안녕하세요 영한님. QueryDsl과 @EntityGraph 사용 기준에 대해 궁금한 부분이 생겨서 질문 남깁니다. fetchJoin을 할 때, 여러가지 방법이 있겠지만 QueryDsl과 @EntityGraph이 가장 편리한 방법이라고 생각합니다. 저의 경우엔 @EntityGraph가 가독성이 더 좋다고 느껴서 간단한 조회용 페치조인의 경우에 사용하고, 검색조건이 있는 복잡한 조회의 경우엔 Querydsl을 사용하는데요. 실제로 이 둘을 사용할 때 어떤 것에 우선순위를 두시는지 궁금합니다. 강의 잘 듣고 있습니다. 감사합니다!
해결됨
Slack 클론 코딩[백엔드 with NestJS + TypeORM]
강의 내용 처럼 postman에서 에러 응답을 받고 싶습니다. 하지만 제대로된 에러 응답을 받지 못하고 있습니다. 시도한 내용 첫번째로, postman에서 post || localhost:3095/api/users 로 body에 아무런 내용없이 send를 보냈습니다. 이후, 에러 응답으로 "msg":"이메일이 없네요." 라는 답을 받았습니다. (성공) body에 이메일을 작성 하여 send를 보냈지만, "msg":"이메일이 없네요." 라는 이전과 동일한 에러응답 을 받았습니다. (실패) 이메일을 send해도 "이메일이 없네요"라는 에러응답으로 답을 받고, 다른 것으로 send를 해도 "이메일이 없네요"라고 에러응답을 받았습니다. 이를 해결하려고 하는데, 참고할만한 코드가 있을까요? users.service.ts @Injectable() export class UsersService { constructor( @InjectRepository(Users) private usersRepository: Repository<Users>, ) {} getUser() {} async join(email: string, nickname: string, password: string) { if (!email) { throw new HttpException('이메일이 없네요', 400); } if (!nickname) { throw new HttpException('닉네임이 없네요', 400); } if (!password) { throw new HttpException('비밀번호가 없네요.', 400); } const user = await this.usersRepository.findOne({ where: { email }}); if (user) { throw new HttpException('등록된 사용자입니다.', 401); } const hashedPassword = await bcrypt.hash(password, 12); await this.usersRepository.save({ email, nickname, password: hashedPassword, }); } } [계속 아래 이미지와 같은 에러 응답만 출력됩니다] 또한, 깃헙에서 코드를 참고하려했으나 아래와 같이 진도가 달라서 어려웠습니다. ㅠㅠ 제로 초님께서 작성해주신 users.service.ts 는 아래 코드 입니다. 완성된 users.service.ts 내용인 것 같아서, 본 강의에 참고하기 어려워서 질문드렸습니다. @Injectable() export class UsersService { constructor( @InjectRepository(Users) private usersRepository: Repository<Users>, @InjectRepository(WorkspaceMembers) private workspaceMembersRepository: Repository<WorkspaceMembers>, @InjectRepository(ChannelMembers) private channelMembersRepository: Repository<ChannelMembers>, private dataSource: DataSource, ) {} async findByEmail(email: string) { return this.usersRepository.findOne({ where: { email }, select: ['id', 'email', 'password'], }); } async join(email: string, nickname: string, password: string) { const queryRunner = this.dataSource.createQueryRunner(); await queryRunner.connect(); await queryRunner.startTransaction(); const user = await queryRunner.manager .getRepository(Users) .findOne({ where: { email } }); if (user) { throw new ForbiddenException('이미 존재하는 사용자입니다'); } const hashedPassword = await bcrypt.hash(password, 12); try { const returned = await queryRunner.manager.getRepository(Users).save({ email, nickname, password: hashedPassword, }); const workspaceMember = queryRunner.manager .getRepository(WorkspaceMembers) .create(); workspaceMember.UserId = returned.id; workspaceMember.WorkspaceId = 1; await queryRunner.manager .getRepository(WorkspaceMembers) .save(workspaceMember); await queryRunner.manager.getRepository(ChannelMembers).save({ UserId: returned.id, ChannelId: 1, }); await queryRunner.commitTransaction(); return true; } catch (error) { console.error(error); await queryRunner.rollbackTransaction(); throw error; } finally { await queryRunner.release(); } } } 해결방법이 있을까요:?
미해결
스프링 부트에서 DTO를 만들 때 @setter을 빼고 @Builder로 하는게 좋다고 들었습니다. 근데 책이랑 구글을 찾아보다 보니 두 가지의 방법으로 하는 것을 봤는데 무슨 차이인지 무엇이 더 좋은 방법인지를 모르겠어서 질문드립니다. 생성자 위에 @Builder를 사용하는 방법 @Getter //Getter 생성 public class LombokPerson { private String name; private String grade; private int age; @Builder // 생성자 만든 후 위에 @Build 어노테이션 적용 public LombokPerson(String name, String grade, int age) { this.name = name; this.grade = grade; this.age = age; } 클래스 위에 @Builder를 사용하면서 @Setter도 사용하는 방법 @ToString @Setter @Getter @Builder @NoArgsConstructor @AllArgsConstructor public class UserDTO { private String token; private String userName; private String password; private String id; } 2번째의 방법이 책에서 나온 방법인데 @Setter이 바뀔 수도 있어서 @Builder로 생성자로 받는거로 알고 있는데 여기서는 @Setter과 @Builder을 같이 쓰더라구여. 이거에 대해서 알려주세요 ㅠㅠ
미해결
java11, springboot2.7.1로 프로젝트 진행했던 프로젝트를 열어 실행하니 에러가 발생합니다. 해결하지 못하여 질문드립니다! 발생에러 11:46:16 AM: Executing ':RandomApplication.main()'... > Task :compileJava FAILED Deprecated Gradle features were used in this build, making it incompatible with Gradle 8.0. You can use '--warning-mode all' to show the individual deprecation warnings and determine if they come from your own scripts or plugins. See https://docs.gradle.org/7.4.1/userguide/command_line_interface.html#sec:command_line_warnings 1 actionable task: 1 executed FAILURE: Build failed with an exception. * What went wrong: Execution failed for task ':compileJava'. > Could not resolve all files for configuration ':compileClasspath'. > Could not find javax.xml.bind:jsxb-api:. Required by: project : * Try: > Run with --stacktrace option to get the stack trace. > Run with --info or --debug option to get more log output. > Run with --scan to get full insights. * Get more help at https://help.gradle.org BUILD FAILED in 652ms 11:46:16 AM: Execution finished ':RandomApplication.main()'. Execution failed for task ':compileJava'. > Could not resolve all files for configuration ':compileClasspath'. > Could not find javax.xml.bind:jsxb-api:. Required by: project : Possible solution: - Declare repository providing the artifact, see the documentation at https://docs.gradle.org/current/userguide/declaring_repositories.html 시도 java JDK 버전 확인, 빌드 자동 실행 설정 등.. 구글링해서 찾아봤으나 해결하지 못했습니다ㅠㅠ 검색해보면 jaxb -api:. 를 기준으로 나오는데, 제 에러는 jsxb -api 입니다 이 둘의 차이는 무엇인가요?
미해결
자바와 스프링 부트로 생애 최초 서버 만들기, 누구나 쉽게 개발부터 배포까지! [서버 개발 올인원 패키지]
안녕하세요 선생님 늘 친절하게 답변해주셔서 감사합니다. 19강에서 궁금한 게 있는데 service와 repository를 스프링 빈으로 만들기 전에 왜 jdbctemplate에 의존할 수밖에 없는 건가요?
미해결
실전! 스프링 부트와 JPA 활용2 - API 개발과 성능 최적화
"/api/v2/simple-orders " 이 url로 호출했을 때, (1) order테이블에서 가져오는 쿼리 1번 => (2개의 데이터) (2) member 쿼리 1번 * 2 (3) delivery 쿼리 1번 * 2 해서 총 5번이 나오는 걸로 알고 있습니다. 근데 현재 로그에서 총 쿼리가 7번이 나가고 있습니다. 코드를 따라쳐보면서 했는데도 왜 다르게 나가는지 원인을 짐작하기가 힘듭니다. 현재 제 쿼리는 (1) order 테이블에서 가져오는 쿼리 1번 (2) member 쿼리 1번 (3) delivery 쿼리 1번 (4) delivery id 조건절로 order 찾는 쿼리 1번 (2)~(4)번 한 번 더 반복 이렇게 해서 총 7번 쿼리가 나가게 됩니다. 쿼리만 보고 어떤 부분때문에 더 나가게 됐는지 짐작할 수 있을까요? 엔티티 간의 연관관계 매핑은 강의를 보면서 했기 때문에 제가 중간에 놓쳤나 생각이 들기도 하네요ㅜ 원인을 짐작하기가 어렵습니다. select o1_0.order_id, o1_0.delivery_id, o1_0.member_id, o1_0.order_date, o1_0.status from orders o1_0 join member m1_0 on m1_0.member_id=o1_0.member_id fetch first ? rows only 2023-03-23T19:03:54.387+09:00 DEBUG 56506 --- [nio-8080-exec-1] org.hibernate.SQL : select m1_0.member_id, m1_0.city, m1_0.street, m1_0.zipcode, m1_0.name from member m1_0 where m1_0.member_id=? 2023-03-23T19:03:54.390+09:00 DEBUG 56506 --- [nio-8080-exec-1] org.hibernate.SQL : select d1_0.delivery_id, d1_0.city, d1_0.street, d1_0.zipcode, d1_0.status from delivery d1_0 where d1_0.delivery_id=? 2023-03-23T19:03:54.393+09:00 DEBUG 56506 --- [nio-8080-exec-1] org.hibernate.SQL : select o1_0.order_id, o1_0.delivery_id, o1_0.member_id, o1_0.order_date, o1_0.status from orders o1_0 where o1_0.delivery_id=? 2023-03-23T19:03:54.395+09:00 DEBUG 56506 --- [nio-8080-exec-1] org.hibernate.SQL : select m1_0.member_id, m1_0.city, m1_0.street, m1_0.zipcode, m1_0.name from member m1_0 where m1_0.member_id=? 2023-03-23T19:03:54.396+09:00 DEBUG 56506 --- [nio-8080-exec-1] org.hibernate.SQL : select d1_0.delivery_id, d1_0.city, d1_0.street, d1_0.zipcode, d1_0.status from delivery d1_0 where d1_0.delivery_id=? 2023-03-23T19:03:54.397+09:00 DEBUG 56506 --- [nio-8080-exec-1] org.hibernate.SQL : select o1_0.order_id, o1_0.delivery_id, o1_0.member_id, o1_0.order_date, o1_0.status from orders o1_0 where o1_0.delivery_id=?
해결됨
[코드캠프] 부트캠프에서 만든 고농축 백엔드 코스
docker로 mysql server를 띄우고 product_category table 에서 전자제품, uuid 를 등록하고 save를 누르면 한글을 인식할 수 없다는 에러가 납니다. 해결방법이 궁금합니다. ERROR [ExceptionsHandler] Incorrect string value: '\xEC\xA3\xBC\xEC\x86\x8C' for column 'address' at row 1
미해결
탄탄한 백엔드 NestJS, 기초부터 심화까지
안녕하세요 다음 연재 강의 주제는 소셜 인증이라고 강의 노트에 써있으나 저에게 프로젝트3는 이번 강의가 마지막인데 맞나요??
해결됨
자바 ORM 표준 JPA 프로그래밍 - 기본편
강사님 강의를 보고 최근에 프로젝트를 하다 궁금한게 생겨 질문 남기게 되었습니다. Product <-> Category Entity 다대다 매핑을 위해 product(OneToMany) <-> product_category(ManyToOne) <-> category(OneToMany) 위와 같은 테이블로 매핑한 상태이고 join 상속 전략으로 district_category 테이블도 생성 하였습니다. district_category를 쿼리 파라미터로 받고 해당 district_category를 갖고 있는 상품들을 검색하고 페이징을 하는 로직을 짠다고 했을때 두가지 방법이 생각났는데 둘 중 어느게 더 적합한지 모르겠습니다 검색어를 바탕으로 product_category에서 Product를 EntityGraph로 같이 찾은 후에 찾은 ProductCategory.getproduct() 와 같은 방식 SearchService Category category = districtCategoryRepository.findByDistrictEnum(districtEnum) .orElseThrow(() -> new ProductException(ProductExceptionType.CATEGORY_NOT_FOUND)); return new ProductCategoryToProductPage(productCategoryRepository.findAllByCategory(pageable, category)); ProductCategoryRepository @EntityGraph(attributePaths = "product") Page<ProductCategory> findAllByCategory(Pageable pageable, Category category); ProductCategoryToProduct public ProductCategoryToProductPage(Page<ProductCategory> page) { this.content.addAll(page.getContent().stream() .map(ProductCategory::getProduct) .map(ProductListGetResponseDTO::new) .collect(toList())); this.totalPages = page.getTotalPages(); this.totalElements = page.getTotalElements(); this.pageNumber = page.getNumber() + 1; this.size = page.getSize(); } 발생 쿼리문 select districtca0_.category_id as category2_1_, districtca0_1_.parent_id as parent_i3_1_, districtca0_.district_enum as district1_2_ from district_category districtca0_ inner join category districtca0_1_ on districtca0_.category_id=districtca0_1_.category_id where districtca0_.district_enum=? select productcat0_.product_category_id as product_1_8_0_, product1_.product_id as product_1_7_1_, productcat0_.category_id as category2_8_0_, productcat0_.product_id as product_3_8_0_, product1_.created_date as created_2_7_1_, product1_.content_detail as content_3_7_1_, product1_.product_content as product_4_7_1_, product1_.product_name as product_5_7_1_, product1_.product_price as product_6_7_1_, product1_.product_status as product_7_7_1_, product1_.product_thumbnail as product_8_7_1_ from product_category productcat0_ left outer join product product1_ on productcat0_.product_id=product1_.product_id where productcat0_.category_id=? limit ? select count(productcat0_.product_category_id) as col_0_0_ from product_category productcat0_ where productcat0_.category_id=? 검색어를 바탕으로 product에서 직접 찾기 (데이터 뻥튀기의 문제는 쿼리dsl 이용 productId로 groupBy로 해결) 글 쓰고 생각해보니 A카테고리는 B라는 상품 안에서는 하나밖에 있을 수가 없으니 굳이 groupBy를 안써도 될거 같네요 SearchService Category category = districtCategoryRepository.findByDistrictEnum(districtEnum) .orElseThrow(() -> new ProductException(ProductExceptionType.CATEGORY_NOT_FOUND)); return productRepository.findAllByCategory(pageable, category); ProductRepository @Override public Page<Product> findAllByCategory(Pageable pageable, Category category) { List<Product> content = queryFactory.selectFrom(product) .join(product.productCategories, productCategory) .where(productCategory.category.categoryId.eq(category.getCategoryId())) .groupBy(product.productId) .offset(pageable.getOffset()) .limit(pageable.getPageSize()) .fetch(); Long total = queryFactory .select(Wildcard.count) .from(product) .join(product.productCategories, productCategory) .where(productCategory.category.categoryId.eq(category.getCategoryId())) .fetchOne(); return new PageImpl<>(content, pageable, total); } 발생 쿼리문 select districtca0_.category_id as category2_1_, districtca0_1_.parent_id as parent_i3_1_, districtca0_.district_enum as district1_2_ from district_category districtca0_ inner join category districtca0_1_ on districtca0_.category_id=districtca0_1_.category_id where districtca0_.district_enum=? select product0_.product_id as product_1_7_, product0_.created_date as created_2_7_, product0_.content_detail as content_3_7_, product0_.product_content as product_4_7_, product0_.product_name as product_5_7_, product0_.product_price as product_6_7_, product0_.product_status as product_7_7_, product0_.product_thumbnail as product_8_7_ from product product0_ inner join product_category productcat1_ on product0_.product_id=productcat1_.product_id where productcat1_.category_id=? group by product0_.product_id limit ? select count(*) as col_0_0_ from product product0_ inner join product_category productcat1_ on product0_.product_id=productcat1_.product_id where productcat1_.category_id=?