Pourquoi utiliser l’instance renvoyée après save () sur le référentiel JPA de Spring Data?

Voici le code:

@Repository public interface AccountRepository extends JpaRepository {} 

JpaRepository du projet JPA Spring Data.

Voici le code de test:

 public class JpaAccountRepositoryTest extends JpaRepositoryTest { @Inject private AccountRepository accountRepository; @Inject private Account account; @Test @Transactional public void createAccount() { Account returnedAccount = accountRepository.save(account); System.out.printf("account ID is %d and for returned account ID is %d\n", account.getId(), returnedAccount.getId()); } } 

Voici le résultat:

 account ID is 0 and for returned account ID is 1 

Voici de CrudReporsitory.save () javadoc:

Enregistre une entité donnée. Utilisez l’instance renvoyée pour d’autres opérations car l’opération de sauvegarde peut avoir complètement modifié l’instance d’entité.

Voici le code réel pour SimpleJpaRepository de Spring Data JPA:

  @Transactional public T save(T entity) { if (entityInformation.isNew(entity)) { em.persist(entity); return entity; } else { return em.merge(entity); } } 

Donc, la question est pourquoi avons-nous besoin d’utiliser l’instance renvoyée au lieu de l’original? (oui, nous devons le faire, sinon nous continuons à travailler avec une instance détachée, mais pourquoi)

La méthode EntityManager.persist () d’origine renvoie void, notre instance est donc associée au contexte de persistance. Y a-t-il de la magie proxy lors de la transmission du compte pour enregistrer dans le référentiel? Est-ce la limitation de l’architecture du projet Spring Data JPA?

La méthode save(…) de l’interface CrudRepository est supposée être abstraite en stockant simplement une entité quel que soit son état. Elle ne doit donc pas exposer l’implémentation spécifique du magasin, même si nouvelles entités à stocker et celles existantes à mettre à jour. C’est pourquoi la méthode s’appelle en réalité save(…) pas create(…) ou update(…) . Nous renvoyons un résultat de cette méthode pour permettre à l’implémentation du magasin de renvoyer une instance complètement différente, car JPA le fait potentiellement lorsque la merge(…) est invoquée.

Donc, en règle générale, la décision de l’API est plutôt d’être indulgente vis-à-vis de la mise en œuvre réelle et donc de mettre en œuvre la méthode de JPA comme nous le faisons. Il n’y a pas de massage proxy supplémentaire effectué sur les entités passées.

Vous avez manqué la deuxième partie: si l’entité n’est pas nouvelle, la merge est appelée. merge copie l’état de son argument dans l’entité attachée avec le même identifiant et renvoie l’entité attachée. Si l’entité n’est pas nouvelle et que vous n’utilisez pas l’entité renvoyée, vous apporterez des modifications à une entité détachée.