[TypeORM] database update시 save() 메서드를 사용하면 주의할점
Updating in the database
Now let's load a single photo from the database, update it and save it:
import { Photo } from "./entity/Photo"
import { AppDataSource } from "./index"
const photoRepository = AppDataSource.getRepository(Photo)
const photoToUpdate = await photoRepository.findOneBy({
id: 1,
})
photoToUpdate.name = "Me, my friends and polar bears"
await photoRepository.save(photoToUpdate)
Now photo with id = 1
will be updated in the database.
공식 문서를 보면 위와 같이 사용자 정보를 최초로 저장할때가 아닌 업데이트 시에도 사용자 객체를 가져와 참조 값을 변경하고 save() 메서드를 사용해서 사용자 정보를 업데이트하도록 나와있다.
공식문서 첫페이지에 나와있는 방법이기에 그대로 그냥 사용했었다.
그런데 프로젝트 진행중 알 수 없는 문제가 발생했다.
데이터를 업데이트하는데 업데이트 되지않고 값이 추가적으로 insert 되는 상황이 발생했다.
MySQL Workbench를 보면 값 업데이트가아닌 추가 되었는데 다시 해당 오류를 재현해보려했지만 동일한 오류를 재현하지 못했다.
typeorm 처음 공부할때 공식문서와 여러 블로그를 봤는데 save() 메서드를 주의해서 사용해야 한다는 내용이있었다.
다시 찾아보니 TypeORM에서 save() 메서드는 entity에 작성되어있는 연결되어있는 모든 PK값을 WHERE 절에 함께 담아 SELECT 쿼리를 실행하게 된다고한다. 이때 PK가 하나라도 누락될 경우 정상적으로 SELECT 결과를 받아오지 못해 INSERT가 발생할 수 있다는 내용이었다.
뿐만 아니라 성능적으로도 최적화를 위해서는 update 메서드를 사용하는게 맞다고 판단되었다.
참고: https://github.com/typeorm/typeorm/issues/680
결과적으로 데이터 업데이트 시에는
1. save() 메서드 대신 .update() 메서드 사용하거나
2. QueryBuilder의 update()를 사용하도록 하자
ex) repository update
await repository.update({ age: 18 }, { category: "ADULT" }) // executes UPDATE user SET category = ADULT WHERE age = 18 await repository.update(1, { firstName: "Rizzrak" }) // executes UPDATE user SET firstName = Rizzrak WHERE id = 1
ex) QueryBuilder update
await dataSource .createQueryBuilder() .update(User) .set({ firstName: "Timber", lastName: "Saw" }) .where("id = :id", { id: 1 }) .execute()
댓글
댓글 쓰기