11
votes

Mise à jour d'un champ dans l'entité JPA

J'ai une entité utilisateur attribué un privilège système dans une fonction. J'ai une page Web où vous sélectionnez un utilisateur à partir d'une liste déroulante et soumettez le formulaire au serveur. Sur le côté serveur, je veux mettre à jour un seul champ pour cette entité.

Mon utilisateur d'utilisateur aura des valeurs par défaut pour tous les objets, à l'exception du champ One qui est défini et son identifiant. Dois-je faire un FindById puis mettez à jour le champ spécifique, puis faites la fusion ou y a-t-il un moyen de dire uniquement à la mise à jour de ce champ?

jpa

0 commentaires

3 Réponses :


9
votes

Dois-je faire un FindByID, puis mettez à jour le champ spécifique, puis faites la fusion

Ce serait l'approche régulière, sauf que vous n'avez pas besoin de fusionner une entité gérée, laissez JPA détecter les modifications et la mettre à jour automatiquement.

ou y a-t-il un moyen de dire à la mise à jour de ce champ?

Non. Mais vous pouvez utiliser une version "courte" de votre utilisateur (avec uniquement le (s) champ (s) à mettre à jour). Une autre option serait d'utiliser une opération de mise à jour mises à jour en vrac mais c'est imo vraiment pas un bon cas d'utilisation. Je n'utiliserais pas cette approche.

Référence
  • Spécification JPA 1.0
    • 4.10 Mise à jour en vrac et Supprimer les opérations


4 commentaires

Qu'entendez-vous par courte version de l'utilisateur?


@geoaxis, @entyty @Table (nom = "utilisateur") CricheRutilisateur de classe {...} serait une entité qui correspond à la même table que utilisateur , mais seulement a un sous-ensemble de colonnes. Il devrait être immuable. Voir Cette question / réponse .


Vous pouvez pré-cacher les résultats de FindByID en mettant en œuvre une technique de radiomessagerie pour rechercher des lots d'entités, puis les augmenter un par un. De cette manière, la FindbyID n'ira pas à la DB pour chaque mise à jour de la ligne.


Trouver l'entité et définir les contournements de champ spécifiques @version Vérification de l'exécution de mes tests dans JPA 2.0 (hibernate 4.2 IIRC). Je devais trouver, détacher, définir des valeurs, puis fusionner pour obtenir @version vérifier, mais qui génère (éventuellement plusieurs) sélectionnées superflues.



8
votes

JPA 2.1 Supporte maintenant les critères de mise à jour qui vous permettent d'utiliser une entité de mise à jour partielle via javax.persistence.criteria.crateriaupdate code>.

javadoc Pe . P>

Exemple code: P>

EntityManagerFactory factory = Persistence.createEntityManagerFactory(PERSISTENCE_UNIT_NAME);
EntityManager em = factory.createEntityManager();

// create user
em.getTransaction().begin();
User user = new User();
user.setUsername("user@example.com");
user.setPassword("password");
user.setCreatedAt(new Date());
em.persist(user);
em.getTransaction().commit();
// end create user

assert user.getId() != 0;

System.out.println("Before update user Date of Birth: " + user.getDateOfBirth());

// update user date of birth
em.getTransaction().begin();
CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaUpdate<User> updateCriteria = cb.createCriteriaUpdate(User.class);
Root<User> root = updateCriteria.from(User.class);
// update dateOfBirth property
updateCriteria.set(root.get("dateOfBirth"), new Date());
// set where clause
updateCriteria.where(cb.equal(root.get("id"), user.getId()));
// update
int affected = em.createQuery(updateCriteria).executeUpdate();
System.out.println("Affected row: " + affected);
em.getTransaction().commit();
// end update user date of birth


// select user again to verify
em.getTransaction().begin();
em.refresh(user);

System.out.println("After update User Date of Birth: " + user.getDateOfBirth());

em.getTransaction().commit();
em.close();


1 commentaires

Critère Date n'est pas une bonne solution pour ce problème. Il est conçu pour Opérations de mise à jour en vrac , il s'agit donc de contourner les contrôles de verrouillage optimistes. Aussi Doc dit: Le contexte de la persistance n'est pas synchronisé avec le résultat de la mise à jour en vrac .



0
votes

Si vous mettez à jour une entité sélectionnée par un client, vous avez deux options.

1) Si l'utilisateur sélectionné est représenté dans le client comme une entité détachée, lorsque vous recevez l'entité utilisateur de votre haricot serveur, il vous suffit d'attribuer la nouvelle valeur de champ, puis effectuez un em.merge (sélectionneur sélectionné ). Cela a l'effet négatif lorsque l'état de l'utilisateur peut avoir changé entre sélection de l'utilisateur sur votre serveur exécutant la mise à jour, ce qui provoque des résultats indésirables.

2) Vous avez simplement le formulaire Soumettre l'ID utilisateur, puis utilisez le FindByID pour rechercher l'utilisateur, modifier votre entité, puis commettre le changement. S'il s'agit d'une unité de persistance gérée de serveur, vous n'avez pas besoin de commettre.


0 commentaires