깊은바다거북
개발 공부 기록
깊은바다거북
전체 방문자
오늘
어제
  • 분류 전체보기 (219)
    • JAVA (9)
    • JavaScript (15)
    • 스파르타코딩클럽 (11)
      • [내일배움단] 웹개발 종합반 개발일지 (5)
      • [내일배움캠프] 프로젝트와 트러블 슈팅 (6)
    • SQL | NoSQL (4)
    • CS 등등 (0)
    • TIL | WIL (173)
    • 기타 에러 해결 (3)
    • 내 살 길 궁리 (4)

인기 글

최근 글

최근 댓글

태그

  • Preorder Traversal(전위 순회)
  • 자료 구조
  • Inorder Traversal(중위 순회)
  • leetcode-cli
  • 혼자 공부하는 자바스크립트
  • 코딩테스트 연습문제
  • Leetcode
  • 최소 힙(Min Heap)
  • Binary Tree(이진 트리)
  • 시간 복잡도
  • 자바스크립트 기초 문법
  • 자잘한 에러 해결
  • 재귀 함수
  • 최대 힙(Max Heap)
  • BST(이진 탐색 트리)
  • 프로그래머스
  • Til
  • tree
  • TypeScript
  • BFS(너비우선탐색)
  • TIT (Today I Troubleshot)
  • 01. 미니 프로젝트
  • DFS(깊이우선탐색)
  • POST / GET 요청
  • Backtracking(백트래킹)
  • 점화식(Recurrence Relation)
  • 트러블 슈팅 Troubleshooting
  • Trie
  • 팀 프로젝트
  • Linked List
hELLO · Designed By 정상우.
깊은바다거북

개발 공부 기록

TIL | WIL

3/1 수 (Nest.js와 TypeORM 에러 모음) TIL

2023. 3. 3. 01:19

(최종 프로젝트 진행중)

TypeORM을 적용한 Nest.js 복습 중 해결한 에러를 간단히 정리했다.


에러 EntityMetadataNotFoundError: No metadata for "User" was found.

발생 상황: npm run start으로 TypeORM 적용한 Nest.js 서버 가동 후 POST http://localhost:3000/user/signup으로 요청보냄.

에러 메세지 전문:

[Nest] 13660  - 2023. 03. 01. 오후 5:50:35   ERROR [ExceptionsHandler] No metadata for "User" was found.
EntityMetadataNotFoundError: No metadata for "User" was found.
    at DataSource.getMetadata (C:\Users\USER\Desktop\Sparta\04.3_nest_practice_with_typeorm\src\data-source\DataSource.ts:418:30)
    at Repository.get metadata [as metadata] (C:\Users\USER\Desktop\Sparta\04.3_nest_practice_with_typeorm\src\repository\Repository.ts:52:40)
    at Repository.findOne (C:\Users\USER\Desktop\Sparta\04.3_nest_practice_with_typeorm\src\repository\Repository.ts:529:42)
    at UserService.getUserInfo (C:\Users\USER\Desktop\Sparta\04.3_nest_practice_with_typeorm\src\user\user.service.ts:46:38)
    at UserService.createUser (C:\Users\USER\Desktop\Sparta\04.3_nest_practice_with_typeorm\src\user\user.service.ts:54:34)
    at UserController.createUser (C:\Users\USER\Desktop\Sparta\04.3_nest_practice_with_typeorm\src\user\user.controller.ts:16:35)
    at C:\Users\USER\Desktop\Sparta\04.3_nest_practice_with_typeorm\node_modules\@nestjs\core\router\router-execution-context.js:38:29
    at InterceptorsConsumer.intercept (C:\Users\USER\Desktop\Sparta\04.3_nest_practice_with_typeorm\node_modules\@nestjs\core\interceptors\interceptors-consumer.js:11:20)
    at C:\Users\USER\Desktop\Sparta\04.3_nest_practice_with_typeorm\node_modules\@nestjs\core\router\router-execution-context.js:46:60
    at C:\Users\USER\Desktop\Sparta\04.3_nest_practice_with_typeorm\node_modules\@nestjs\core\router\router-proxy.js:9:23

시도: 찾아보니 app.module.ts 에 imports하는 entities에 User를 빼먹어서 그렇다고 한다.

// app.module.ts

@Module({
    imports: [
      TypeOrmModule.forRoot({
        ...
        entities: [User] // User를 추가해줘야 함. 
        ...
      }),
      ...
    ],
})

내 경우는 TypeOrmModule > useClass를 이용하여 ormConfig에 데이터베이스 설정을 담아두었으므로, 다음과 같았다:

// app.module.ts
import { TypeOrmConfigService } from './config/typeorm.congif.service';

@Module({
  imports: [
    ConfigModule.forRoot({ isGlobal: true }), 
    TypeOrmModule.forRootAsync({
      useClass: TypeOrmConfigService, 
      imports: [ConfigModule],
      inject: [ConfigService],
    }),
		...
	],
})

// config/typeorm.congif.service
@Injectable()
export class TypeOrmConfigService implements TypeOrmOptionsFactory {
  constructor(private readonly configService: ConfigService) {}

  createTypeOrmOptions(): TypeOrmModuleOptions {
    return {
      type: 'mysql',
      ...
      // entities: [__dirname + '/**/*.entity{.ts,.js}'],
      entities: [Article],
			...
    };
  }
}

원인: 결국 app.module이 user.entity 파일에 정의된 “User” DB모델을 인식할 수 있도록 ‘entities’ 옵션에 나열해줘야 했다.

해결: (app.module.ts에 쓰이는) ormConfig 파일에 User 모델을 임포트하고 ‘entities’ 옵션에 넣어주니 해결되었다.

// config/typeorm.congif.service
import { User } from 'src/user/user.entity';

@Injectable()
export class TypeOrmConfigService implements TypeOrmOptionsFactory {
  constructor(private readonly configService: ConfigService) {}

  createTypeOrmOptions(): TypeOrmModuleOptions {
    return {
      type: 'mysql',
      ...
      // entities: [__dirname + '/**/*.entity{.ts,.js}'],
      entities: [Article, User],
			...
    };
  }
}

(참고: https://stackoverflow.com/questions/51562162/no-metadata-for-user-was-found-using-typeorm)

에러 Error: secretOrPrivateKey must have a value

발생 상황: npm run start으로 TypeORM 적용한 Nest.js 서버 가동 후 POST http://localhost:3000/user/signup으로 요청보냄.

에러 메세지 전문:

[Nest] 6096  - 2023. 03. 01. 오후 6:06:08   ERROR [ExceptionsHandler] secretOrPrivateKey must have a value
Error: secretOrPrivateKey must have a value
    at Object.module.exports [as sign] (C:\Users\USER\Desktop\Sparta\04.3_nest_practice_with_typeorm\node_modules\jsonwebtoken\sign.js:105:20)
    at C:\Users\USER\Desktop\Sparta\04.3_nest_practice_with_typeorm\node_modules\@nestjs\jwt\dist\jwt.service.js:33:53
    at new Promise (<anonymous>)
    at JwtService.signAsync (C:\Users\USER\Desktop\Sparta\04.3_nest_practice_with_typeorm\node_modules\@nestjs\jwt\dist\jwt.service.js:33:16)
    at UserService.createUser (C:\Users\USER\Desktop\Sparta\04.3_nest_practice_with_typeorm\src\user\user.service.ts:67:47)
    at processTicksAndRejections (node:internal/process/task_queues:95:5)
    at UserController.createUser (C:\Users\USER\Desktop\Sparta\04.3_nest_practice_with_typeorm\src\user\user.controller.ts:16:12)
    at C:\Users\USER\Desktop\Sparta\04.3_nest_practice_with_typeorm\node_modules\@nestjs\core\router\router-execution-context.js:46:28
    at C:\Users\USER\Desktop\Sparta\04.3_nest_practice_with_typeorm\node_modules\@nestjs\core\router\router-proxy.js:9:17

시도: process.env.JWT_KEY 뭔가 이걸 인식하지 못하고 있어서라고 해서 생각해보니, 나 JWT 시크릿 키 어디서 불러오고 있지? 설정해준 기억이 없다.

원인: JwtService가 JWT 토큰을 생성하고 검사하는 데 필요한 secret key가 제대로 인식되지 못해서 생긴 문제이다. 한 마디로 .env 파일에 JWT_SECRET 값을 만들어주지 않아서였다. 구체적으로는, app.module.ts와 user.module.ts에 사용되는 jwtConfig에 시크릿 키 옵션으로 지정해놓은 값이 제대로 읽히지 못해 발생한 에러라고 보면 되겠다.

// src/user/user.module.ts
import { JwtModule } from '@nestjs/jwt'
import { JwtConfigService } from 'src/config/jwt.config.service';

@Module({
  imports: [
		...
    JwtModule.registerAsync({
      imports: [ConfigModule],
      useClass: JwtConfigService,
      inject: [ConfigService],
    }),
  ],
	...
})
// 
import { Injectable } from '@nestjs/common';
import { ConfigService } from '@nestjs/config';
import { JwtModuleOptions, JwtOptionsFactory } from '@nestjs/jwt';

@Injectable()
export class JwtConfigService implements JwtOptionsFactory {
  constructor(private readonly configService: ConfigService) {}

  createJwtOptions(): JwtModuleOptions {
    return {
      secret: this.configService.get<string>('JWT_SECRET'),
      signOptions: { expiresIn: '3600s' },
    };
  }
}
// 3. 환경 변수를 읽어오는 ConfigService가 읽어오는 파일인 .env
DATABASE_HOST="localhost"
...
JWT_SECRET="my_secret_key" // 이 줄이 없었음.

해결: 위와 같이 .env 파일에 JWT_SECRET 값을 지정해주니 해결되었다.

(참고: https://stackoverflow.com/questions/58673430/error-secretorprivatekey-must-have-a-value)

에러 QueryFailedError: ER_DATA_TOO_LONG: Data too long for column 'password' at row 1

발생 상황: npm run start으로 TypeORM 적용한 Nest.js 서버 가동 후 PUT http://localhost:3000/user/update으로 유저 정보 수정 요청을 보냄.

// src/user/user.controller.ts
@Controller('user')
export class UserController {
	...
  @Put('/update')
  updateUser() {
    this.userService.updateUser('userId2', 'new_name', 'new_password');
  }
}

⇒ ‘userId2’를 Id로 가진 유저의 name을 “new_name”으로, password를 “new_password”로 업데이트하고자 함.

에러 메세지 전문:

C:\Users\USER\Desktop\Sparta\04.3_nest_practice_with_typeorm\src\driver\mysql\MysqlQueryRunner.ts:222
                                new QueryFailedError(query, parameters, err),
                                ^
QueryFailedError: ER_DATA_TOO_LONG: Data too long for column 'password' at row 1
    at Query.<anonymous> (C:\Users\USER\Desktop\Sparta\04.3_nest_practice_with_typeorm\src\driver\mysql\MysqlQueryRunner.ts:222:33)
    at Query.<anonymous> (C:\Users\USER\Desktop\Sparta\04.3_nest_practice_with_typeorm\node_modules\mysql\lib\Connection.js:526:10)
    at Query._callback (C:\Users\USER\Desktop\Sparta\04.3_nest_practice_with_typeorm\node_modules\mysql\lib\Connection.js:488:16)
    at Query.Sequence.end (C:\Users\USER\Desktop\Sparta\04.3_nest_practice_with_typeorm\node_modules\mysql\lib\protocol\sequences\Sequence.js:83:24)
    at Query.ErrorPacket (C:\Users\USER\Desktop\Sparta\04.3_nest_practice_with_typeorm\node_modules\mysql\lib\protocol\sequences\Query.js:92:8)
    at Protocol._parsePacket (C:\Users\USER\Desktop\Sparta\04.3_nest_practice_with_typeorm\node_modules\mysql\lib\protocol\Protocol.js:291:23)
    at Parser._parsePacket (C:\Users\USER\Desktop\Sparta\04.3_nest_practice_with_typeorm\node_modules\mysql\lib\protocol\Parser.js:433:10)
    at Parser.write (C:\Users\USER\Desktop\Sparta\04.3_nest_practice_with_typeorm\node_modules\mysql\lib\protocol\Parser.js:43:10)
    at Protocol.write (C:\Users\USER\Desktop\Sparta\04.3_nest_practice_with_typeorm\node_modules\mysql\lib\protocol\Protocol.js:38:16)
    at Socket.<anonymous> (C:\Users\USER\Desktop\Sparta\04.3_nest_practice_with_typeorm\node_modules\mysql\lib\Connection.js:88:28)

시도:

password 부분이 문제라길래 설마설마하며 ‘new_password’ → ‘new_pass’로 바꿔 실행해보았다. 그러니 잘 되는 것을 확인했다…

원인: 에러 메세지 그대로, MySQL에서 삽입하려고 하는 데이터가 해당 컬럼의 Length 값보다 큰 길이의 값일 때 발생하는 에러였다. 현재 User 모델을 찾아가보니 다음과 같이 password 필드의 길이 한도는 10으로 되어있었다:

// src/user/user.entity.ts
import ...

@Entity({ schema: 'board', name: 'users' })
export class User {
	...
  @Column('varchar', { length: 10, select: false })
  password: string;

  ...
}

해결:

선택1. 해당 컬럼의 Length에 설정된 값보다 작은 길이를 넣어준다.

⇒ ‘new_password’ 는 12자. 따라서 ‘new_passwd’ 같이 한도인 10자 내로 바꿔준다.

선택2. 해당 컬럼의 Length값 자체를 늘려준다.

// src/user/user.entity.ts
@Entity({ schema: 'board', name: 'users' })
export class User {
	...
  @Column('varchar', { length: 30, select: false })
  password: string;

  ...
}

해결된 모습:

iduserIdnamepasswordcreatedAtupdatedAtdeletedAt
1userIdnamepasswordWed Mar 01 2023 18:06:08 GMT+0900 (한국 표준시)Wed Mar 01 2023 18:06:08 GMT+0900 (한국 표준시)null
2userId2new_namenew_passwdWed Mar 01 2023 19:00:22 GMT+0900 (한국 표준시)Wed Mar 01 2023 19:27:00 GMT+0900 (한국 표준시)null

배운 점:

아주 간단한 문제였다. TypeORM의 모델에서 length 값이 실제로 일하는 모습을 보게 되어 좋았다. ;;


Uploaded by N2T

    'TIL | WIL' 카테고리의 다른 글
    • 3/3 금 (Nest.js 공식 문서를 후루룩) TIL
    • 3/2 목 (Git Rebase 조사중) TIL
    • 2/28 화 (최종 프로젝트에 돌입하다) TIL
    • 2/23 목 (지지부진해서 미안해) TIL
    깊은바다거북
    깊은바다거북

    티스토리툴바