[문제]
SQL 쿼리(query)문을 작성하고 실행하니 바로 500 Internal Server Error 메시지가 떴다. 이 정도면 저 오류 메시지를 보려고 리팩토링(refactoring)하는 게 아닌가 싶었다.
[원인]
package com.spring.weekthree.repository;
import com.spring.weekthree.dto.responsedto.PlanResponseDto;
import com.spring.weekthree.entity.Plan;
import org.springframework.http.HttpStatus;
import org.springframework.jdbc.core.*;
import org.springframework.jdbc.core.namedparam.MapSqlParameterSource;
import org.springframework.jdbc.core.simple.SimpleJdbcInsert;
import org.springframework.stereotype.Repository;
import org.springframework.web.server.ResponseStatusException;
import javax.sql.DataSource;
import java.sql.*;
import java.sql.Date;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.*;
// Data Access Layer(Repository Layer)
@Repository
public class JdbcTemplatePlanRepository implements PlanRepository {
private final JdbcTemplate jdbcTemplate;
public JdbcTemplatePlanRepository(DataSource dataSource) {
this.jdbcTemplate = new JdbcTemplate(dataSource);
}
@Override
public PlanResponseDto save(Plan plan) {
SimpleJdbcInsert jdbcInsert;
jdbcInsert = new SimpleJdbcInsert(jdbcTemplate);
jdbcInsert.withTableName("planner").
usingGeneratedKeyColumns("id");
Map<String, Object> parameters = new HashMap<>();
parameters.put("name", plan.getName());
parameters.put("password", plan.getPassword());
parameters.put("plannedDate", plan.getPlannedDate());
parameters.put("title", plan.getTitle());
parameters.put("task", plan.getTask());
parameters.put("createdDateTime", plan.getCreatedDateTime());
parameters.put("updatedDateTime", plan.getUpdatedDateTime());
Number key = jdbcInsert.executeAndReturnKey(
new MapSqlParameterSource(parameters
)
);
return new PlanResponseDto(
key.longValue(),
plan.getName(),
plan.getPlannedDate(),
plan.getTitle(),
plan.getTask(),
plan.getCreatedDateTime(),
plan.getUpdatedDateTime());
}
@Override
public List<PlanResponseDto> fetchAllPlans(
String name,
LocalDate updatedDate
) {
StringBuilder sql;
sql = new StringBuilder("SELECT * FROM planner WHERE 1=1");
List<Object> params = new ArrayList<>();
if (name != null) {
sql.append(" AND BINARY name = ? ");
params.add(name);
}
/*
[수정 전] sql.append("AND BINARY name = ? ");
[수정 후] sql.append(" AND BINARY name = ? ");
*/
if (updatedDate != null) {
Date updatedDateSql = Date.valueOf(updatedDate);
sql.append(" AND DATE(updatedDateTime) = ? ");
params.add(updatedDateSql);
}
/*
[수정 전] sql.append("AND DATE(updatedDateTime) = ? ");
[수정 후] sql.append(" AND DATE(updatedDateTime) = ? ");
*/
sql.append(" ORDER BY updatedDateTime DESC");
/*
[수정 전] sql.append("ORDER BY updatedDateTime DESC");
[수정 후] sql.append(" ORDER BY updatedDateTime DESC");
*/
List<PlanResponseDto> allPlans;
allPlans = jdbcTemplate.query(
sql.toString(),
plannerRowMapper(),
params.toArray()
);
return allPlans;
}
@Override
public Plan fetchPlanById0rElseThrow(Long id) {
List<Plan> result = jdbcTemplate.query(
"SELECT * FROM planner WHERE id =?",
plannerRowMapperEach(),
id
);
return result.stream()
.findAny()
.orElseThrow(
() -> new ResponseStatusException(
HttpStatus.NOT_FOUND,
"Id does no exist id = " + id
)
);
}
@Override
public int updatePatchInRepository(
Long id,
String name,
LocalDate plannedDate,
String title,
String task,
LocalDateTime updatedDateTime
) {
return jdbcTemplate.update(
"UPDATE planner SET " +
"name = ?, " +
"plannedDate = ?, " +
"title = ?, " +
"task = ?, " +
"updatedDateTime = ? " +
"WHERE id = ?",
name,
plannedDate,
title,
task,
updatedDateTime,
id
);
}
@Override
public void deletePlan(Long id) {
jdbcTemplate.update(
"DELETE FROM planner WHERE id = ?",
id
);
}
private RowMapper<PlanResponseDto> plannerRowMapper() {
return new RowMapper<PlanResponseDto>() {
@Override
public PlanResponseDto mapRow(ResultSet rs, int rowNum) throws SQLException {
return new PlanResponseDto(
rs.getLong("id"),
rs.getString("name"),
rs.getDate("plannedDate").toLocalDate(),
rs.getString("title"),
rs.getString("task"),
rs.getTimestamp("createdDateTime").toLocalDateTime(),
rs.getTimestamp("updatedDateTime").toLocalDateTime()
);
}
};
}
private RowMapper<Plan> plannerRowMapperEach() {
return new RowMapper<Plan>() {
@Override
public Plan mapRow(ResultSet rs, int rowNum) throws SQLException {
return new Plan(
rs.getLong("id"),
rs.getString("name"),
rs.getString("password"),
rs.getDate("plannedDate").toLocalDate(),
rs.getString("title"),
rs.getString("task"),
rs.getTimestamp("createdDateTime").toLocalDateTime(),
rs.getTimestamp("updatedDateTime").toLocalDateTime()
);
}
};
}
}
원인은 띄어쓰기를 제대로 쓰지 않은 데에 있었다. 띄어쓰기가 없으니, 문장이 추가될 때마다 두 단어가 하나로 합쳐지며 이상한 문장이 완성되었다. SQL을 처음 공부하는 티가 쿼리(query)문을 작성할 때 바로 드러날 줄이야.
[해결]
문제를 해결한 뒤에는 처음에 구현한 대로 조회 기능이 제대로 작동했다. 혹시나 하는 마음에 작성자 이름을 의미하는 name과 수정 날짜 및 시간인 updatedDateTime을 수정 날짜로 바꾸어서 조회했는데, 다행히 오류 없이 원하는 일정만 볼 수 있었다.
[결과 수치화]
[수정 전] 500 Internal Server Error 1건 발생
[수정 후] 500 Internal Server Error 0건 발생, 200 OK 메시지 생성 및 조건에 맞추어 일정 목록 및 단건 조회 성공
'Troubleshooting: 무엇이 문제였는가? > 본캠프 3주 차: 일정 관리 앱 만들기' 카테고리의 다른 글
3단계: "사용자 Id를 입력했는데 왜 자꾸 0이 나오니?" (0) | 2024.12.12 |
---|---|
2단계: "PATCH를 두 번 눌러야 수정이 돼요. 왜 이럴까요?" (0) | 2024.12.09 |
1단계: "아무래도 이름(name)이란 체에 구멍이 뻥 뚫렸나 보다." (0) | 2024.12.08 |
2단계: "왜 수정 날짜를 수정하려고 하니!" (0) | 2024.12.08 |
1단계: "@NoArgsConstructor가 굴린 대형 눈덩이" (0) | 2024.12.08 |