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

Eh bien la question dit à peu près tout. Utilisation de JPARepository Comment mettre à jour une entité?

JPARepository n’a qu’une méthode de sauvegarde , qui ne me dit pas si elle est créée ou mise à jour. Par exemple, j’insère un object simple dans l’utilisateur de la firebase database, qui comporte trois champs: prénom, nom et âge:

@Entity public class User { private Ssortingng firstname; private Ssortingng lastname; //Setters and getters for age omitted, but they are the same as with firstname and lastname. private int age; @Column public Ssortingng getFirstname() { return firstname; } public void setFirstname(Ssortingng firstname) { this.firstname = firstname; } @Column public Ssortingng getLastname() { return lastname; } public void setLastname(Ssortingng 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, je “sauve” simplement, qui à ce stade est un insert en fait:

  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); 

Ok tout va bien. Maintenant, je veux mettre à jour cet utilisateur, par exemple changer son âge. Eh bien, je pourrais utiliser une requête pour que QueryDSL ou NamedQuery, peu importe. Mais, vu que je veux juste utiliser spring-data-jpa et le JPARepository, comment puis-je lui dire qu’au lieu d’un insert je veux faire une mise à jour?

Plus précisément, comment dire à spring-data-jpa que les utilisateurs qui ont le même nom d’utilisateur et le même prénom sont en réalité EQUAL et sont censés mettre à jour l’entité. Déranger les égaux n’a pas fonctionné.

Je vous remercie!

L’identité des entités est définie par leurs clés primaires. Comme firstname et lastname ne font pas partie de la clé primaire, vous ne pouvez pas demander à JPA de traiter les User s avec le même firstname s et le même lastname s que s’ils ont des userId différents.

Ainsi, si vous souhaitez mettre à jour un User identifié par son firstname et son lastname , vous devez rechercher cet User par une requête, puis modifier les champs appropriés de l’object trouvé. Ces modifications seront vidées automatiquement dans la firebase database à la fin de la transaction, afin que vous n’ayez rien à faire pour enregistrer ces modifications de manière explicite.

MODIFIER:

Je devrais peut-être élaborer sur la sémantique globale de JPA. Il existe deux approches principales pour concevoir des API de persistance:

  • approche d’insertion / mise à jour . Lorsque vous devez modifier la firebase database, vous devez appeler explicitement les méthodes de l’API de persistance: vous appelez insert pour insérer un object ou pour update à update nouvel état de l’object dans la firebase database.

  • Approche de l’unité de travail . Dans ce cas, vous avez un ensemble d’objects gérés par la bibliothèque de persistance. Toutes les modifications que vous apportez à ces objects seront vidées automatiquement dans la firebase database à la fin de l’unité de travail (à la fin de la transaction en cours, par exemple). Lorsque vous devez insérer un nouvel enregistrement dans la firebase database, vous devez gérer l’ object correspondant. Les objects gérés sont identifiés par leurs clés primaires. Ainsi, si vous créez un object avec une clé primaire prédéfinie gérée , il sera associé à l’enregistrement de firebase database du même identifiant, et l’état de cet object sera automatiquement propagé.

JPA suit l’approche ultérieure. save() dans Spring Data JPA est soutenu par merge() dans JPA simple, par conséquent, votre entité est gérée comme décrit ci-dessus. Cela signifie que l’appel à save() sur un object avec un identifiant prédéfini mettra à jour l’enregistrement de la firebase database correspondante plutôt que d’en insérer un nouveau, et explique également pourquoi save() n’est pas appelé create() .

Puisque la réponse de @axtavt se concentre sur JPA pas sur spring-data-jpa

Mettre à jour une entité en interrogeant puis en sauvegardant n’est pas efficace car elle nécessite deux requêtes et la requête peut être assez coûteuse car elle peut rejoindre d’autres tables et charger des collections fetchType=FetchType.EAGER

Spring-data-jpa prend en charge l’opération de mise à jour.
Vous devez définir la méthode dans l’interface du référentiel et l’annoter avec @Query et @Modifying .

 @Modifying @Query("update User u set u.firstname = ?1, u.lastname = ?2 where u.id = ?3") void setUserInfoById(Ssortingng firstname, Ssortingng lastname, Integer userId); 

@Query sert à définir une requête personnalisée et @Modifying à spring-data-jpa que cette requête est une opération de mise à jour et qu’elle requirejs executeUpdate() pas executeQuery() .

En utilisant spring-data-jpa save (), j’avais le même problème que @DtechNet. Je veux dire que chaque save () créait un nouvel object au lieu d’une mise à jour. Pour résoudre ce problème, j’ai dû append “version” à l’entité et à la table associée.

Voici comment j’ai résolu le problème:

 User inbound = ... User existing = userRepository.findByFirstname(inbound.getFirstname()); if(existing != null) inbound.setId(existing.getId()); userRepository.save(inbound);