waawo535
@waawo535 (ひなす)

Are you sure you want to delete the question?

If your question is resolved, you may close it.

Leaving a resolved question undeleted may help others!

We hope you find it useful!

MyBatisにてキャメルケースのフィールド名とスネークケースの列名が自動的にマッピングされない

MyBatisを用いて、SQLで取得した結果データをブラウザに表示しようとしています。

image.png

スネークケースであるテーブルの列名とキャメルケースであるエンティティのフィールド名を自動的にマッピングさせることができません。
以下に経緯を記します。

ソースコード

簡潔に見せるため、createdAtフィールド以外のフィールドは省略しています。
インポート文も省略しています。

Entity.java
@Data 
@NoArgsConstructor
@AllArgsConstructor
public class Entity {
	private LocalDateTime createdAt;
}
MapperInterface.java
@Mapper
public interface MapperInterface {
	List<Entity> selectAll();
}
MapperFile.xml
<?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.java
@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";
	}
}
view.html
<!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のこの部分を

view.html
<td th:text="${todos.createdAt.format(T(java.time.format.DateTimeFormatter)
               .ofPattern('yyyy/MM/dd HH:mm:ss'))}"></td>

このように変更すると、

view.html
<td th:text="${todos.createdAt!=null?'nullではないです':'nullです'}"></td>

エラーは出ずに「nullです」と表示されるため、「todos.createdAt」がnullになってしまってることがわかりました。

試しにエンティティのフィールド名を列名と同じ「created_at」に書き換えたところ、ブラウザ上に正常に結果が表示されました。
このため、スネークケースである列名とキャメルケースであるフィールド名が自動的にマッピングされていないということがわかりました。

自分で試したこと

マッピングされない問題を解決するために、「src/main/resources」直下に「mybatis-config.xml」を作成し、以下の内容を記述しました。

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では、デフォルトではスネークケースの列名とキャメルケースのフィールド名は自動的にはマッピングされない」といった認識で間違いないでしょうか。

もしおわかりになる方いらっしゃいましたらご教授お願いいたします。

0

1Answer

application.propertiesに以下を追加したら、改善しますか?
(追加済でしたら、すいません!)

mybatis.config-location=classpath:mybatis-config.xml
1Like

Comments

  1. @waawo535

    Questioner

    回答ありがとうございます!教えていただいた方法を試してみたら改善しました。Spring Bootアプリケーションにmybatis-config.xmlが認識されておらず、明示的にapplication.propertiesに記述する必要があったということですね!本当に助かりました!

  2. 明示的にapplication.propertiesに記述する必要があった

    はい、そのとおりです!解決してよかったです! 

Your answer might help someone💌