MyBatisにてキャメルケースのフィールド名とスネークケースの列名が自動的にマッピングされない
MyBatisを用いて、SQLで取得した結果データをブラウザに表示しようとしています。
スネークケースであるテーブルの列名とキャメルケースであるエンティティのフィールド名を自動的にマッピングさせることができません。
以下に経緯を記します。
ソースコード
簡潔に見せるため、createdAtフィールド以外のフィールドは省略しています。
インポート文も省略しています。
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Entity {
private LocalDateTime createdAt;
}
@Mapper
public interface MapperInterface {
List<Entity> selectAll();
}
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.example.webapp.repository.MapperInterface">
<!-- 全件表示 -->
<select id="selectAll" resultType="com.example.webapp.entity.Entity">
SELECT * FROM todos;
</select>
</mapper>
@Controller
@RequestMapping("/todos")
@RequiredArgsConstructor
public class Controller {
private final MapperInterface mapperInterface;
@GetMapping
public String list(Model model) {
model.addAttribute("todos",mapperInterface.selectAll());
return "todo/view";
}
}
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title></title>
</head>
<body>
<table border="1">
<tr>
<th>日時</th>
<td th:text="${todos.createdAt.format(T(java.time.format.DateTimeFormatter)
.ofPattern('yyyy/MM/dd HH:mm:ss'))}"></td>
</tr>
</table>
</body>
</html>
発生している問題・エラー
これを実行しブラウザで表示しようとすると、「Whitelabel Error Page」が表示されて以下のようなエラーが出ました。
Caused by: org.attoparser.ParseException: Exception evaluating SpringEL expression: "todo.createdAt.format(T(java.time.format.DateTimeFormatter).ofPattern('yyyy/MM/dd HH:mm:ss'))" (template: "todo/detail" - line 20, col 8)
Caused by: org.thymeleaf.exceptions.TemplateProcessingException: Exception evaluating SpringEL expression: "todo.createdAt.format(T(java.time.format.DateTimeFormatter).ofPattern('yyyy/MM/dd HH:mm:ss'))" (template: "todo/detail" - line 20, col 8)
Caused by: org.springframework.expression.spel.SpelEvaluationException: EL1011E: Method call: Attempted to call method format(java.time.format.DateTimeFormatter) on null context object
上記のエラー内容から、原因がview.htmlの<td>タグ内の記述にあることがわかります。
そこで、view.htmlのこの部分を
<td th:text="${todos.createdAt.format(T(java.time.format.DateTimeFormatter)
.ofPattern('yyyy/MM/dd HH:mm:ss'))}"></td>
このように変更すると、
<td th:text="${todos.createdAt!=null?'nullではないです':'nullです'}"></td>
エラーは出ずに「nullです」と表示されるため、「todos.createdAt」がnullになってしまってることがわかりました。
試しにエンティティのフィールド名を列名と同じ「created_at」に書き換えたところ、ブラウザ上に正常に結果が表示されました。
このため、スネークケースである列名とキャメルケースであるフィールド名が自動的にマッピングされていないということがわかりました。
自分で試したこと
マッピングされない問題を解決するために、「src/main/resources」直下に「mybatis-config.xml」を作成し、以下の内容を記述しました。
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<settings>
<!-- キャメルケースとスネークケースの自動マッピング -->
<setting name="mapUnderscoreToCamelCase" value="true"/>
</settings>
</configuration>
キャメルケースとスネークケースの自動マッピングの設定をし、これで解決かと思いきや、これでも自動マッピングがされていないみたいでエラーが直りませんでした。
質問
・「mybatis-config.xml」を作成し自動マッピングの設定をしてもなお改善しない理由を教えてください。
・自動的にマッピングさせるようにする設定方法を教えてください。
・「MyBatisでは、デフォルトではスネークケースの列名とキャメルケースのフィールド名は自動的にはマッピングされない」といった認識で間違いないでしょうか。
もしおわかりになる方いらっしゃいましたらご教授お願いいたします。