Spring JpaRepository – Détacher et attacher une entité

J’utilise bottes de spring et hibernate sur jpa. J’utilise l’interface JpaRepository pour implémenter mes référentiels. Comme avec UserRepository suivant

public interface UserRepository extends JpaRepository { } 

Je veux atteindre les objectives suivants

  1. Charger une entité utilisateur.
  2. Changer l’état de l’object entité, par exemple user.setName (“foo”)
  3. Effectuez un appel de service Web système externe. Enregistrer le résultat de l’appel dans la firebase database
  4. Enregistrez le nouvel état d’utilisateur dans le référentiel uniquement si l’appel de service Web a réussi.

Toutes les étapes ci-dessus ne se produisent pas dans une transaction, c’est-à-dire que l’appel de service externe est hors transaction.

Lorsque je sauvegarde le résultat de mon service Web dans la firebase database via son référentiel, mes modifications dans l’entité Utilisateur sont également enregistrées. D’après ma compréhension, cela est dû au flou du contexte de persistance de la sous-couche à l’étape 3. Après quelques recherches sur Google, je pense pouvoir atteindre mon objective si je peux détacher mon entité utilisateur à la première étape et la rattacher à l’étape 4. Merci de confirmer. si ma compréhension est correcte et comment je peux y arriver? Il n’y a pas de méthode dans l’interface JpaRepository pour détacher une entité.

Voici le code pour illustrer

 public void updateUser(int id, Ssortingng name, int changeReqId){ User mUser = userRepository.findOne(id); //1 mUser.setName(name); //2 ChangeRequest cr = changeRequestRepository.findOne(changeReqId); ChangeResponse rs = userWebService.updateDetails(mUser); //3 if(rs.isAccepted()){ userRepository.saveAndFlush(mUser); //4 } cr.setResponseCode(rs.getCode()); changeRequestRepository.saveAndFlush(cr); //this call also saves the changes at step 2 } 

Merci

Si vous utilisez JPA 2.0, vous pouvez utiliser EntityManager # detach () pour dissocier une entité du contexte de persistance. De plus, Hibernate a une session # evict () qui sert le même but.

Comme JpaRepository ne fournit pas cette fonctionnalité elle-même, vous pouvez lui append une implémentation personnalisée.

 public interface UserRepositoryCustom { ... void detachUser(User u); ... } public interface UserRepository extends JpaRepository, UserRepositoryCustom { ... } @Repository public class UserRepositoryCustomImpl implements UserRepositoryCustom { ... @PersistenceContext private EntityManager entityManager; @Override public void detachUser(User u) { entityManager.detach(u); } ... } 

Je n’ai pas essayé ce code, mais vous devriez pouvoir le faire fonctionner. Vous pourriez même essayer de maîsortingser EntityManager dans votre classe de service (où updateUser() est) avec @PersistenceContext et éviter la coercition de l’ajout d’une implémentation personnalisée au référentiel.

entityManager.clear() déconnectera tous les objects JPA, ce qui peut ne pas être une solution appropriée dans tous les cas, si vous avez d’autres objects que vous prévoyez de restr connectés.

clair

 /** * Clear the persistence context, causing all managed * entities to become detached. Changes made to entities that * have not been flushed to the database will not be * persisted. */ public void clear(); 

entityManager.detach(entity); Supprimer l’entité donnée du contexte de persistance

détacher

 /** * Remove the given entity from the persistence context, causing * a managed entity to become detached. Unflushed changes made * to the entity if any (including removal of the entity), * will not be synchronized to the database. Entities which * previously referenced the detached entity will continue to * reference it. * @param entity entity instance * @throws IllegalArgumentException if the instance is not an * entity * @since Java Persistence 2.0 */ public void detach(Object entity);