wake-up-neo.com

Warum löst getOne (...) in einem Spring Data-Repository keine EntityNotFoundException aus?

Ich arbeite an einem seltsamen Problem. Ich habe Integrationstests durchgeführt und meinen Controller aufgerufen, um ein Objekt aus der Datenbank abzurufen, das nicht vorhanden ist.

public Optional<T> get(Long id) {

  try {
    return Optional.ofNullable(repository.getOne(id));
  } catch(EntityNotFoundException e) {
    return Optional.empty();
  }
}

Wenn getOne(…) nichts finden kann, habe ich eine EntityNotFoundException erwartet, aber eigentlich nichts. Wenn ich mein Ergebnis inspiziere, kann ich sehen, dass ich eine leere Entität mit einem Handler-Link dazu habe "warf EntityNotFoundException", aber wir gehen nicht in den Haken und ich gebe eine Option dieser seltsamen Entität zurück.

Ich kann dieses Verhalten nicht verstehen.

18
Seb

Dies liegt an der Art und Weise, wie JPA EntityManager.getReference(…) spezifiziert. Es soll einen Proxy zurückgeben, der entweder das Objekt auflöst, das beim ersten Zugriff auf eine Eigenschaft zurückgegeben wird, oder die enthaltene Ausnahme schließlich auslöst.

Die einfachste Möglichkeit, dies zu umgehen, besteht darin, stattdessen einfach findOne(…) zu verwenden, wie hier Optional.ofNullable(repository.findOne(…)). findOne(…) gibt null zurück, falls kein Ergebnis gefunden wird.

Eine fortgeschrittenere Methode zur Lösung dieses Problems besteht darin, das Repository Optional-Instanzen direkt zurückgeben zu lassen. Dies kann erreicht werden, indem eine benutzerdefinierte Basis-Repository-Schnittstelle mit Optional<T> als Rückgabetyp für die find…- Methoden erstellt wird.

interface BaseRepository<T, ID extends Serializable> extends Repository<T, ID> {

  Optional<T> findOne(ID id);

  // declare additional methods if needed
}

interface YourRepository extends BaseRepository<DomainClass, Long> { … }

Ein vollständiges Beispiel finden Sie im Repository für Spring Data-Beispiele .

26
Oliver Drotbohm

So hat es für mich funktioniert

public User findUserById(Long id) {
    return userRepository.findById(id).orElse(null);
}
0
VK321