N:M tag 부분 구현 중 findOne 조회 부분 에러
products.service.ts에서 create 부근에 tag를 저장 하기 전 tag를 미리 조회하는 부분을 구현 중인데 findOne에서 {name: tagname} 을 구현하려고 할 때 다음과 같은 에러가 발생합니다. save에서는 에러가 발생하지 않는데 findOne 조회 부분만 에러가 발생하네요

관련된 코드 같이 보내드립니다.
createProduct.input.ts
import { InputType, Field, Int } from '@nestjs/graphql';
import { Min } from 'class-validator';
import { ProductSaleslocationInput } from 'src/apis/productsSaleslocation/entities/dto/productSaleslocation.input';
@InputType()
export class CreateProductInput {
@Field(() => String)
name: string;
@Field(() => String)
description: string;
@Min(0)
@Field(() => Int)
price: number;
@Field(() => ProductSaleslocationInput)
productSaleslocation: ProductSaleslocationInput;
@Field(() => String)
productCategotyId: string;
@Field(() => [String])
productTags: string[];
}
products.entity.ts
import { Field, Int, ObjectType } from '@nestjs/graphql';
import { ProductCategory } from 'src/apis/productsCategory/entities/productsCategory.entity';
import { ProductTag } from 'src/apis/productsTags/productTags.entity';
import { User } from 'src/apis/users/users.entity';
import {
Column,
DeleteDateColumn,
Entity,
JoinColumn,
JoinTable,
ManyToMany,
ManyToOne,
OneToOne,
PrimaryGeneratedColumn,
} from 'typeorm';
import { ProductSaleslocation } from '../../productsSaleslocation/entities/productsSaleslocation.entity';
@Entity()
@ObjectType()
export class Product {
@PrimaryGeneratedColumn('uuid')
@Field(() => String)
id: string;
@Field(() => String)
@Column()
name: string;
@Field(() => String)
@Column()
description: string;
@Field(() => Int)
@Column()
price: number;
@Field(() => Boolean)
@Column({ default: false })
isSoldout: boolean;
@DeleteDateColumn()
deletedAt: Date;
@Field(() => ProductSaleslocation)
@JoinColumn()
@OneToOne(() => ProductSaleslocation)
productSaleslocation: ProductSaleslocation;
@Field(() => ProductCategory)
@ManyToOne(() => ProductCategory)
productCategory: ProductCategory;
@Field(() => User)
@ManyToOne(() => User)
user: User;
@JoinTable()
@ManyToMany(() => ProductTag, (productTags) => productTags.products)
@Field(() => [ProductTag])
productTags: ProductTag[];
}
productTags.entity.ts
import { Field, ObjectType } from '@nestjs/graphql';
import { Column, Entity, ManyToMany, PrimaryGeneratedColumn } from 'typeorm';
import { Product } from '../products/entities/products.entity';
@Entity()
@ObjectType()
export class ProductTag {
@Field(() => String)
@PrimaryGeneratedColumn('uuid')
id: string;
@Column()
@Field(() => String)
name: string;
@Field(() => [Product])
@ManyToMany(() => Product, (products) => products.productTags)
products: Product[];
}
products.service.ts
import { Product } from './entities/products.entity';
import { Injectable, UnprocessableEntityException } from '@nestjs/common';
import { Repository } from 'typeorm';
import { InjectRepository } from '@nestjs/typeorm';
import { ProductSaleslocation } from '../productsSaleslocation/entities/productsSaleslocation.entity';
import { ProductTag } from '../productsTags/productTags.entity';
@Injectable()
export class ProductService {
constructor(
@InjectRepository(Product)
private readonly productRepository: Repository<Product>,
@InjectRepository(ProductSaleslocation)
private readonly productSaleslocationRepository: Repository<ProductSaleslocation>,
@InjectRepository(ProductTag)
private readonly productTagRepository: Repository<ProductTag>,
) {}
async findAll() {
return await this.productRepository.find({
relations: ['productSaleslocation', 'productCategory', 'productTags'],
});
}
async findOne({ productId }) {
return await this.productRepository.findOne({
where: { id: productId },
relations: ['productSaleslocation', 'productCategory', 'productTags'],
});
}
async create({ createProductInput }) {
// 1. 상품만 등록하는 경우
// const result = await this.productRepository.save({
// ...createProductInput,
// // 하나 하나 직접 나열하는 방식
// // name: createProductInput.name,
// // description: createProductInput.description,
// // price: createProductInput.price,
// });
// 2. 상품과 상품거래 위치 같이 등록
const { productSaleslocation, productCategotyId, productTag, ...product } =
createProductInput;
const result = await this.productSaleslocationRepository.save({
...productSaleslocation,
});
// productTag // ["#electronics, #computer"]
const result2 = []; // [{name: ..., id: ...}]
for (let i = 0; i < productTags.length; i++) {
const tagName = productTags[i].replace('#', '');
// check the tags that has already registered
const checkTag = await this.productTagRepository.findOne({
name: tagName,
});
// if the tags has been existed
if (checkTag) {
result2.push(checkTag);
// if the tags hasn't been existed
} else {
const newTag = await this.productTagRepository.save({ name: tagName });
result2.push(newTag);
}
}
const result3 = await this.productRepository.save({
...product,
productSaleslocation: result, // result 통째로 넣기 vs id만 넣기
productCategory: { id: productCategotyId },
productTags: result2,
});
return result3;
}
async update({ productId, updateProductInput }) {
const myProduct = await this.productRepository.findOne({
where: { id: productId },
});
const newProduct = {
...myProduct,
id: productId,
...updateProductInput,
};
return await this.productRepository.save(newProduct);
}
async checkSoldOut({ productId }) {
const product = await this.productRepository.findOne({
where: { id: productId },
});
if (product.isSoldout) {
throw new UnprocessableEntityException('Sold out');
}
// if(product.isSoldout) {
// throw new HttpException('이미 판매 완료 된 상품입니다.', HttpStatus.UNPROCESSABLE_ENTITY)
// }
}
async delete({ productId }) {
// 1. 실제 삭제
// const result = await this.productRepository.delete({ id: productId });
// return result.affected ? true : false
// 2. 소프트 삭제(직접 구현) - isDeleted
// this.productRepository.update({ id: productId }, { isDeleted: true });
// 3. 소프트 삭제(직접 구현) - deletedAt
// this.productRepository.update({ id: productId }, { deletedAt: new Date() });
// 4. 소프트 삭제(TypeORM 제공) - softRemove - id로만 삭제 가능
// this.productRepository.softRemove({ id: productId });
// 4 . 소프트 삭제(TypeORM 제공) - softDelete
const result = await this.productRepository.softDelete({ id: productId });
return result.affected ? true : false;
}
}
내용 확인 부탁드립니다.
답변 2
0
안녕하세요. 유상우님
해당 코드로 테스트를 실행해 본 결과, 에러없이 작동되는 것을 확인하였습니다. 따라서 최근 Nest 업데이트로 인해 typeorm이 상이하게 작동하는 것으로 추측됩니다. 감사합니다.
그래프 ql 문서 사용할때 느낌표 남는거 어떻게 없애나요?
0
86
2
강의 전체 소스 코드를 받고싶습니다.
0
77
2
fontawesome 사용 문의
0
81
2
소스 코드 부탁드립니다~
0
87
2
깃 레포지터리 소스
0
87
2
커리큘럼12.css 정렬 에 나오는 과제 정답알고싶어요
0
74
2
10-01 Entity TypeOrmModule.forRoot 에 entities
0
89
3
강의 버전관련 문의입니다
0
104
2
Ubuntu 설치 관련
0
62
1
schema.gql 질문 드립니다.
0
51
1
서버 재실행시 Many to Many
0
102
3
input 관련 문의
0
90
2
Rest API 보다는 graphql이 주된 내용인데
0
134
2
강의 전체 소스코드 받을수있을까요?
0
156
1
도커볼륨 마운트 관련
0
127
2
findOne 타입스크립트오류
0
109
1
http => htrtps 호출 인증서 신뢰 오류
0
356
1
self-signed certificate in certificate chain 에러 발생
0
421
1
mongoose 설치 오류
0
143
1
특정 API, 특정 IP 허용 (단일경로에 CORS 활성화)
0
285
2
08-06
0
180
3
구조랑 패턴 관련해서 질문
0
126
2
mydocker
0
129
2
coolsms statuscode 2000 인데 전송안돼는 경우 확인.
0
156
1





