fee-fi-fo-fum
๋ฐ˜์‘ํ˜•
<code />
2023-10-08 05:21:35.706 ERROR 6064 --- [nio-8080-exec-2] o.a.c.c.C.[.[.[/].[dispatcherServlet] : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.springframework.dao.InvalidDataAccessResourceUsageException: could not execute statement; SQL [n/a]; nested exception is org.hibernate.exception.SQLGrammarException: could not execute statement] with root cause org.postgresql.util.PSQLException: ์˜ค๋ฅ˜: r.recruitid ์นผ๋Ÿผ ์—†์Œ Hint: ์•„๋งˆ "r.recruit_id" ์นผ๋Ÿผ์„ ์ฐธ์กฐํ•˜๋Š” ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค. Position: 91

nativeQuery = false ํ•˜๋‹ˆ๊นŒ ํ•ด๊ฒฐ

@Transactional ํ•˜๋‹ˆ๊นŒ ํ•ด๊ฒฐ

<code />
@Transactional @Modifying @Query(value = "update Recruit r set r.position = :position, r.bonus = :bonus, r.detail = :detail, r.technique = :technique where r.recruitId = :id", nativeQuery = false) public int changeAll(@Param("position") String position, @Param("bonus") Long bonus, @Param("detail") String detail, @Param("technique") String technique, @Param("id") Long id); }
<code />
@Transactional public void patchRecruit(Recruit recruit) { Recruit findedRecruit = recruitRepository.findById(recruit.getRecruitId()).orElseThrow(); recruitRepository.changeAll(recruit.getPosition(),recruit.getBonus(), recruit.getDetail(), recruit.getTechnique(),recruit.getRecruitId()); }

1. ๊ธฐ๋ณธํ‚ค ๋งคํ•‘์— ๋Œ€ํ•œ ์ดํ•ด

https://velog.io/@tritny6516/JPA-%EA%B8%B0%EB%B3%B8%ED%82%A4Primary-Key-%EB%A7%A4%ED%95%91-Id-GeneratedValue

2. ๋งต์ŠคํŠธ๋Ÿญ์Šค ์‚ฌ์šฉ์ค‘ ์—๋Ÿฌ

๋งต์ŠคํŠธ๋ŸญํŠธ ์‚ฌ์šฉ์ค‘์— ๊ณ„์† ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•˜์˜€๋‹ค.

<code />
@Builder public class RecruitResponseDto { private Long recruitId; private String companyName; private String nation; private String region; private String position; private Long bonus; private String technique; }
<code />
default List<RecruitResponseDto> recruitListToRecruitResponseDtos(List<Recruit> recruitList){ List<RecruitResponseDto> recruitResponseDtos = new ArrayList<>(); for(Recruit recruit : recruitList){ Company company = recruit.getCompany(); RecruitResponseDto recruitResponseDto = RecruitResponseDto.builder() .recruitId(recruit.getRecruitId()) .region(company.getRegion()) .bonus(recruit.getBonus()) .nation(company.getNation()) .companyName(company.getName()) .position(recruit.getPosition()) .technique(recruit.getTechnique()) .build(); recruitResponseDtos.add(recruitResponseDto); } return recruitResponseDtos; }

์ด๋ ‡๊ฒŒ ๋Œ๋ฆฌ๋‹ˆ๊นŒ ๋ฐœ์ƒํ•˜๋Š” ์—๋Ÿฌ๋Š” ์—„์ฒญ ๋งŽ์•˜๋Š”๋ฐ
@Getter๋ฅผ ์ถ”๊ฐ€ํ•ด์ฃผ๋‹ˆ๊นŒ ์ •์ƒ๋™์ž‘ํ•œ๋‹ค.

3. ์ฟผ๋ฆฌ

<code />
@Query("SELECT r FROM Recruit r WHERE " + "r.position LIKE %:search% OR " + "CAST(r.bonus AS string) LIKE %:search% OR " + "r.detail LIKE %:search% OR " + "r.technique LIKE %:search% OR " + "r.company.name LIKE %:search% OR " + "r.company.nation LIKE %:search% OR " + "r.company.region LIKE %:search% ") List<Recruit> findRecruitsBySearchString(@Param("search") String search); }

๋ชจ๋“ ๊ฑธ ์กฐํšŒํ•˜๋Š” ์ฟผ๋ฆฌ๋ฅผ ์ž‘์„ฑํ•˜๋ ค๋ฉด ์ด๋Ÿฐ์‹์œผ๋กœ ํ•ด์•ผํ•œ๋‹ค. queryDSL๊ฐ™์€ ๊ธฐ์ˆ  ์ ์šฉ์—†์ด ๊ทธ๋ƒฅ ๋ƒ…๋‹ค ๋•Œ๋ ค๋ฐ•์€๊ฑฐ๋‹ค. ์ด๊ฑฐ ๊ทผ๋ฐ ๋ฌธ์ œ๊ฐ€ ์žˆ๋‹ค. ๋ญ๋ƒ๋ฉด

<code />
{ "recruitId": 14, "companyName": "์›ํ‹ฐ๋“œ๋žฉ", "nation": "ํ•œ๊ตญ", "region": "์„œ์šธ", "position": "๋ฐฑ์—”๋“œ ์ฃผ๋‹ˆ์–ด ๊ฐœ๋ฐœ์ž", "bonus": 1000000, "technique": "Python" }, { "recruitId": 15, "companyName": "๋„ค์ด๋ฒ„", "nation": "ํ•œ๊ตญ", "region": "ํŒ๊ต", "position": "๋ฐฑ์—”๋“œ ์ฃผ๋‹ˆ์–ด ๊ฐœ๋ฐœ์ž", "bonus": 1000000, "technique": "Python" }, { "recruitId": 16, "companyName": "์›ํ‹ฐ๋“œ์ฝ”๋ฆฌ์•„", "nation": "ํ•œ๊ตญ", "region": "๋ถ€์‚ฐ", "position": "๋ฐฑ์—”๋“œ ์ฃผ๋‹ˆ์–ด ๊ฐœ๋ฐœ์ž", "bonus": 1000000, "technique": "Python" }, { "recruitId": 17, "companyName": "์นด์นด์˜ค", "nation": "ํ•œ๊ตญ", "region": "ํŒ๊ต", "position": "๋ฐฑ์—”๋“œ ์ฃผ๋‹ˆ์–ด ๊ฐœ๋ฐœ์ž", "bonus": 1500000, "technique": "Python" } ]

๋ถ„๋ช… ์›ํ‹ฐ๋“œ๋ฅผ ๊ฒ€์ƒ‰์–ด๋กœ ๋„ฃ์—ˆ๋Š”๋ฐ ์นด์นด์˜ค๊ฐ€ ๋‚˜์™€๋ฒ„๋ฆฌ๋„ค..? ๊ทผ๋ฐ ์ด์œ ๋ฅผ ์ฐพ์•˜๋‹ค...ใ…‹ใ…‹ใ…‹
"r.detail LIKE %:search% OR " +
์ด๋ถ€๋ถ„์ด ๋ฌธ์ œ์˜€๋‹ค. detail์€ response๋กœ ํ‘œ์‹œ๋˜์ง„์•Š์ง€๋งŒ DB๋ฅผ ํ™•์ธํ•ด๋ณด๋‹ˆ
์›ํ‹ฐ๋“œ๋žฉ์—์„œ ๋ฐฑ์—”๋“œ ์ฃผ๋‹ˆ์–ด ๊ฐœ๋ฐœ์ž๋ฅผ ์ฑ„์šฉํ•ฉ๋‹ˆ๋‹ค. ์ž๊ฒฉ์š”๊ฑด์€.. ์š”๋ ‡๊ฒŒ ์จ์ ธ์žˆ๋˜๊ฒƒ..! ์ง€์›Œ์ฃผ๋‹ˆ๊นŒ ์ •์ƒ๋™์ž‘ํ•œ๋‹ค.

4. JPQL์—์„œ Long > String ๋ฐ”๊พธ๊ธฐ

<code />
"CAST(r.bonus AS string) LIKE %:search% OR "

์ด๋Ÿฐ์‹์œผ๋กœ ์‚ฌ์šฉํ•˜๋ฉด ๋œ๋‹ค!

5. detail ๊ตฌํ˜„์—์„œ

๋ฌธ์ œ์ ์ด ์žˆ๋Š”๋ฐ ์ง€๊ธˆ ํ‘œ์ถœ๋˜๋Š”๊ฒŒ ํ˜„์žฌ ์ž์„ธํžˆ๋ณด๊ธฐ๋ฅผ ๋ˆŒ๋ฅธ ๊ฒƒ๊นŒ์ง€ ํšŒ์‚ฌ๊ฐ€ ์˜ฌ๋ฆฐ ๋‹ค๋ฅธ ์ฑ„์šฉ๊ณต๊ณ ์— ํ‘œ์ถœ๋œ๋‹ค ์ด๋ถ€๋ถ„ ๋ฐ”๊ฟ”์ค˜์•ผํ•œ๋‹ค.

๋ฐ˜์‘ํ˜•
profile

fee-fi-fo-fum

@hae02y

ํฌ์ŠคํŒ…์ด ์ข‹์•˜๋‹ค๋ฉด "์ข‹์•„์š”โค๏ธ" ๋˜๋Š” "๊ตฌ๋…๐Ÿ‘๐Ÿป" ํ•ด์ฃผ์„ธ์š”!