web-dev-qa-db-fra.com

Pourquoi getOne (…) sur un référentiel Spring Data ne déclenche-t-il pas une exception EntityNotFoundException?

Je travaillais sur un problème étrange, je faisais des tests d'intégration, appelant mon contrôleur pour obtenir un objet de la base de données qui n'existe pas.

public Optional<T> get(Long id) {

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

Lorsque getOne(…) n'est pas en mesure de trouver quoi que ce soit, je m'attendais à un EntityNotFoundException mais en réalité rien. Si j'inspecte mon résultat, je constate que j'ai une entité vide avec un lien de gestionnaire qui lui est associé "jeté EntityNotFoundException" mais nous n'allons pas dans la capture et je retourne une option de cette entité étrange.

Je ne peux pas comprendre ce comportement.

18
Seb

Cela est dû à la façon dont JPA a spécifié que EntityManager.getReference(…) fonctionnait. Il est censé renvoyer un proxy qui résoudra l'objet à renvoyer lors du premier accès à une propriété ou rejettera éventuellement l'exception contenue.

Le moyen le plus simple de contourner ce problème consiste à utiliser simplement findOne(…), comme ceci Optional.ofNullable(repository.findOne(…)). findOne(…) retournera nulldans le cas où aucun résultat n'est trouvé.

Une façon plus avancée de résoudre ce problème consiste à faire en sorte que le référentiel renvoie directement les instances Optional. Cela peut être réalisé en créant une interface de référentiel de base personnalisée utilisant Optional<T> comme type de retour pour les méthodes find…-.

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> { … }

Vous en trouverez un exemple complet dans le référentiel d'exemples Spring Data .

26
Oliver Drotbohm

Voici comment cela a fonctionné pour moi

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