317 votes

Comment mettre à jour une entité en utilisant spring-data-jpa ?

La question dit à peu près tout. En utilisant JPARepository, comment mettre à jour une entité ?

JPARepository n'a qu'un sauver ce qui ne me permet pas de savoir s'il s'agit d'une création ou d'une mise à jour. Par exemple, j'insère un simple objet dans la base de données User, qui comporte trois champs : firstname , lastname et age :

 @Entity
 public class User {

  private String firstname;
  private String lastname;
  //Setters and getters for age omitted, but they are the same as with firstname and lastname.
  private int age;

  @Column
  public String getFirstname() {
    return firstname;
  }
  public void setFirstname(String firstname) {
    this.firstname = firstname;
  }

  @Column
  public String getLastname() {
    return lastname;
  }
  public void setLastname(String lastname) {
    this.lastname = lastname;
  }

  private long userId;

  @Id
  @GeneratedValue(strategy=GenerationType.AUTO)
  public long getUserId(){
    return this.userId;
  }

  public void setUserId(long userId){
    this.userId = userId;
  }
}

Ensuite, j'appelle simplement save() qui, à ce stade, est en fait une insertion dans la base de données :

 User user1 = new User();
 user1.setFirstname("john"); user1.setLastname("dew");
 user1.setAge(16);

 userService.saveUser(user1);// This call is actually using the JPARepository: userRepository.save(user);

Jusqu'à présent, tout va bien. Maintenant, je veux mettre à jour cet utilisateur, par exemple changer son âge. Pour ce faire, je pourrais utiliser une requête, soit QueryDSL ou NamedQuery, peu importe. Mais, étant donné que je veux juste utiliser spring-data-jpa et le JPARepository, comment puis-je lui dire qu'au lieu d'une insertion, je veux faire une mise à jour ?

Plus précisément, comment puis-je dire à spring-data-jpa que les utilisateurs ayant le même nom d'utilisateur et le même prénom sont en fait ÉGAUX et que l'entité existante est censée être mise à jour ? La surcharge de equals n'a pas résolu ce problème.

1voto

Golam Kibria Points 1

Vous pouvez voir l'exemple ci-dessous :

private void updateDeliveryStatusOfEvent(Integer eventId, int deliveryStatus) {
    try {
        LOGGER.info("NOTIFICATION_EVENT updating with event id:{}", eventId);
        Optional<Event> eventOptional = eventRepository.findById(eventId);
        if (!eventOptional.isPresent()) {
            LOGGER.info("Didn't find any updatable notification event with this eventId:{}", eventId);
        }
        Event event = eventOptional.get();
        event.setDeliveryStatus(deliveryStatus);
        event = eventRepository.save(event);
        if (!Objects.isNull(event)) {
            LOGGER.info("NOTIFICATION_EVENT Successfully Updated with this id:{}", eventId);
        }
    } catch (Exception e) {
        LOGGER.error("Error :{} while updating NOTIFICATION_EVENT of event Id:{}", e, eventId);
    }
}

Ou mettre à jour à l'aide d'une requête native :

public interface YourRepositoryName extends JpaRepository<Event,Integer>{
@Transactional
    @Modifying
    @Query(value="update Event u set u.deliveryStatus = :deliveryStatus where u.eventId = :eventId", nativeQuery = true)
    void setUserInfoById(@Param("deliveryStatus")String deliveryStatus, @Param("eventId")Integer eventId);
}

1voto

Comme indiqué dans d'autres réponses, la méthode save() est une fonction double. Elle peut à la fois sauvegarder ou mettre à jour, elle est automatiquement mise à jour si vous fournissez l'identifiant.

Pour la méthode de mise à jour dans la classe du contrôleur, j'ai suggéré d'utiliser @PatchMapping.

Méthode de sauvegarde POST

{
    "username": "jhon.doe",
    "displayName": "Jhon",
    "password": "xxxyyyzzz",
    "email": "jhon.doe@mail.com"
}
@PostMapping("/user")
public void setUser(@RequestBody User user) {
    userService.save(user);
}

Mise à jour de la méthode PATCH

{
    "id": 1, // this is important. Widly important
    "username": "jhon.doe",
    "displayName": "Jhon",
    "password": "xxxyyyzzz",
    "email": "jhon.doe@mail.com"
}

@PatchMapping("/user")
public void patchUser(@RequestBody User user) {
    userService.save(user);
}

Vous vous demandez peut-être d'où viennent les identifiants. Ils proviennent de la base de données bien sûr, vous voulez mettre à jour les données existantes, n'est-ce pas ?

0voto

sanku Points 11

Si votre clé primaire est autoincrémentée, vous devez définir la valeur de la clé primaire. pour que la méthode save() ; fonctionne comme update().else, elle créera un nouvel enregistrement dans la base de données.

si vous utilisez un formulaire jsp, utilisez un fichier caché pour définir la clé primaire.

Jsp :

<form:input type="hidden" path="id" value="${user.id}"/>

Java :

@PostMapping("/update")
public String updateUser(@ModelAttribute User user) {
    repo.save(user);
    return "redirect:userlist";
}

Regardez également ceci :

@Override
  @Transactional
  public Customer save(Customer customer) {

    // Is new?
    if (customer.getId() == null) {
      em.persist(customer);
      return customer;
    } else {
      return em.merge(customer);
    }
  }

0voto

Tarek Sahalia Points 35

Utilisation @DynamicUpdate est plus propre et il n'est pas nécessaire d'interroger la base de données pour obtenir les valeurs sauvegardées.

0voto

gjuliane Points 1

C'est ce que j'ai fait pour mon entité UserModel :

Dans le contrôleur :

        @PutMapping("/{id}")
        public Optional<UserModel> update(@RequestBody UserModel user, @PathVariable Long id) {
            return this.userService.update(user, id);
        }

Et dans le service :

    public Optional<UserModel> update(UserModel req, Long id){
        Optional<UserModel> user = userRepository.findById(id);
        if (user != null) {
            userRepository.save(req);
        }
        return user;
    }

Exemple avec le facteur : Exemple de méthode PUT de Postman

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X