はじめに
SpringBootでアプリ開発をしている中で、更新前後のオブジェクトの内容を比較し、差異がある場合だけUPDATE処理を実行する、ということをしたかったのですが、equalsメソッドをそのまま使ってもうまくいかなかったのでオーバーライドの方法を残しておきます。
やりたいこと
手軽にオブジェクトの中身の比較をして、差異がある場合だけ処理を実装するような条件分岐をしたい
エラー内容
エラーはでないが、期待した処理をしない
// 問題の処理
if (!modifiedStudent.equals(currentStudent)) {
studentRepository.updateStudent(modifiedStudent);
}
// 参考:updatteStudentメソッドの内容
@Update(
"UPDATE students SET full_name = #{student.fullName}, kana = #{student.kana}, nick_name = #{student.nickName}, email = #{student.email}, city = #{student.city}, age = #{student.age}, gender = #{student.gender}, remark = #{student.remark} "
+ "WHERE id = #{student.id}"
)
void updateStudent(@Param("student") Student student);
原因
- equalsメソッドがオーバーライドされていない
-
equalsメソッドの実装
public boolean equals(Object obj) { return (this == obj);
-
equalsメソッドの機能
- equalsを呼び出したインスタンスと、引数として渡すobjが実体として同じかを確認している
- 実体として同じであるということ
-
全く同じインスタンスであるということ
-
フィールドの内容が全く同じであっても、別のオブジェクトとしてインスタンス化されていれば、別のインスタンスとして評価される
Student student1 = new Student(); Student student2 = new Student(); System.out.println(student1.equals(student2)); // false System.out.println(student1.equals(student1)); // true
-
-
デフォルトのオーバーライド機能を使うと、以下のif文は常にfalseを返す
if (modifiedStudent.equals(currentStudent)) { ... }
-
解決策
-
equalsメソッドをオーバーライドする
public class Student { private String id; private String fullName; private String kana; private String nickName; private String email; private String city; private int age; private Gender gender; private String remark; private Boolean isDeleted; @Override public boolean equals(Object o) { if (this == o) { return true; } if (o == null || getClass() != o.getClass()) { return false; } Student student = (Student) o; return age == student.age && Objects.equals(id, student.id) && Objects.equals( fullName, student.fullName) && Objects.equals(kana, student.kana) && Objects.equals(nickName, student.nickName) && Objects.equals(email, student.email) && Objects.equals(city, student.city) && gender == student.gender && Objects.equals(remark, student.remark) && Objects.equals(isDeleted, student.isDeleted); }
- なにをしているのか
- equalsを呼び出したインスタンスと引数にとったオブジェクトについて以下を返す
- 実体として同じであればtrue
- nullまたは違うクラスのインスタンスであればfalse
- フィールドの値がどこかしら異なればfalse
- フィールドの値が完全に一致すればtrue
- equalsを呼び出したインスタンスと引数にとったオブジェクトについて以下を返す
- なにをしているのか
おわりに
IDEの機能を使えば簡単に実装できました。