2010-05-10 6 views
4

Travailler avec JPA/Hibernate dans un environnement Web OSIV me rend fou;)fusion/Remontage de JPA/Hibernate sans mettre à jour la DB

Après scénario: J'ai une entité A qui est chargée par JPA et a une collection d'entités B. Ces entités B ont un champ obligatoire. Lorsque l'utilisateur ajoute un nouveau B à A en appuyant sur un lien dans la webapp, ce champ requis n'est pas défini (puisqu'il n'y a pas de valeur par défaut sensible).

Lors de la requête http suivante, le filtre OSIV tente de fusionner l'entité A, mais cela échoue car Hibernate se plaint que le nouveau champ B n'a pas de champ obligatoire.

javax.persistence.PersistenceException: org.hibernate.PropertyValueException: not-null property references a null or transient value 

Lire la spécification JPA, je ne vois pas le signe que ces contrôles sont nécessaires dans la phase de fusion (je n'ai aucune transaction active)

Je ne peux pas garder la collection de l'extérieur de B de A et seulement les ajouter à A quand l'utilisateur appuie sur « enregistrer » (alias entitymanager.persist()) comme le lieu où le bouton d'enregistrement est ne sait pas sur le B, seulement A.

également A et B sont des exemples, J'ai des trucs similaires partout ..

Des idées? Est-ce que d'autres implémentations JPA se comportent de la même manière ici?

Merci d'avance.

Répondre

2

J'ai beaucoup lu et testé. Le problème vient de mon incompréhension de JPA/Hibernate. merge() effectue toujours un hit sur la base de données et planifie également une mise à jour pour l'entité. Je n'ai trouvé aucune mention de cela dans la spécification JPA, mais le livre 'Java Persistence with Hibernate' le mentionne. En regardant à travers l'API EntityManager (et Session as fallback), il semble qu'il n'y ait aucun moyen d'assigner une entité au contexte persistant actuel sans avoir à planifier une mise à jour. Après tout, ce que je veux, c'est naviguer dans le graphe d'objets, changer les propriétés au besoin et déclencher une mise à jour (avec vérification de la version si nécessaire) plus tard. Quelque chose que je pense que chaque Webapp utilisant ORM doit faire?

Le flux de travail de base que je recherche pour:

  1. charge une entité de la DB (ou en créer un nouveau)
  2. laissez l'entité (et toutes ses associations se détachent (comme les ferme EntitManager à la fin d'une requête HTTP)
  3. lorsque la requête HTTP suivante arrive, travailler à nouveau avec ces objets, naviguer dans l'arbre sans crainte de LazyInitExceptions
  4. appel d'une méthode qui persiste toutes les modifications apportées au cours 1-3)

Avec le filtre OSIV du printemps en conjonction avec une implémentation IModel du portillon, j'ai pensé que je l'ai archivé.

Je vois essentiellement 2 façons possibles sortir:

a) charger l'entité et toutes les associations nécessaires lors de la saisie d'une certaine page (cas d'utilisation), les laisser se détachent, en ajoutant/les changer au besoin en le cours de plusieurs requêtes http. Rattachez-les lorsque l'utilisateur lance une sauvegarde (les validateurs assureront un état valide) et soumettez-les à la base de données.B) utiliser la configuration actuelle, mais assurez-vous que toutes les entités nouvellement ajoutées ont tous leurs champs obligatoires (probablement en utilisant certains composants de l'assistant). j'aurais toujours toutes les mises à jour à la base de données pour chaque merge(), mais j'espère que l'administrateur de base de données ne réalisera pas;)

Comment les autres personnes travaillent-elles avec JPA dans un environnement Web? D'autres options pour moi?

Questions connexes