🐙
JpaRepositoryのgetByIdはLazy Load
結論
JpaRepositoryのgetById
は該当レコードが存在しない場合はEntityNotFoundException
を投げるみたい。これは永続プロバイダー次第だけど、ほとんどがそのようになっているそうな。
しかもLazy loadなので、getByIdを実行直後に例外が発生するのではなくて、戻り値を最初にアクセスしたときに例外を出すということだった。
javadocにちゃんとそう書いてあった。
自分で作ったメソッドfindByCodeなどはレコードがない場合にnullが返ってくるので注意が必要。
経緯
getById
は該当するレコードがない場合はnullを返すものと勝手に思い込んでいた。
Optional<Circle> findById(long id) {
CircleRecord record = CircleRepository.getById(id);
return mapRecordToEntity(record);
}
Optional<Circle> mapRecordToEntity(CircleRecord record) {
if (record == null) {
return Optional.empty();
}
return new Optional.of(Circle(
record.getId(),
record.getName()
));
}
すると、record.getId()
のところで、EntityNotFoundExceptionが出ることに気づいた。
id
= 1でfindById
を呼び出してデバッグすると、record
のid
は0だった。
getById
のjavadocで調べてみると、最初にアクセスした時点でEntityNotFoundExceptionが発生するということだった。
レコードのエンティティは取得してすぐにドメインのエンティティに詰め替えるので、詰め替える場所をEntityNotFoundExceptionのtry catchで挟むだけでよかったので負担が少なかった。
Optional<Circle> mapRecordToEntity(CircleRecord record) {
if (record == null) {
return Optional.empty();
}
try {
return new Optional.of(Circle(
record.getId(),
record.getName()
));
} catch (EntityNotFoundException e) {
return Optional.empty();
}
}
Discussion