8
votes

Hibernate - comment persister que le parent, garder les enfants comme ils sont

Quelqu'un peut-il m'aider s'il vous plaît comprendre comment configurer Hibernate pour faire ce que je veux.

J'ai une entité parent "appartement" avec une liste de "chambre" comme des enfants. J'ai un formulaire pour éditer "l'appartement" et dans ce formulaire, j'ai répertorié toutes les enfants "Salle" S juste à des fins informatives. Les chambres sont ajoutées et éditées sous une forme séparée.

Donc, donc parce que je liste les chambres de l'appartement, j'ai défini la luisheding sur false: xxx

Mais si je modifie un appartement et que je le stocke, tous les pièces appartements disparaissent soudainement. Dans la base de données, ils ne sont pas supprimés, mais déréférencés (comme dans l'apparition = null).

alors comment puis-je configurer Hibernate pour ne perverser mon appartement. Et ne pas toucher les enfants du tout?

Ceci est mon enregistrement-action: xxx


4 commentaires

Reconstructez-vous l'objet avant de la stocker? Il semble que vous retirez la salle S de votre liste, explicitement ou en créant une nouvelle liste vide.


Je viens d'ajouter mon métode de sauvegarde ci-dessus. Comme vous pouvez le voir, je ne fais rien vraiment à l'objet appartement avant de le stocker ..


Où est-ce que appartement vient? (Note latérale: c'est orthographié appartement ;-)


Eh bien, être assez nouveau à Struts2, je ne peux que l'imaginer que cela devrait être le même objet qui est défini dans la méthode Edit (). La méthode d'édition teste l'ID pour NULL et si NOT NULL obtient l'objet-objet de la base de données. Si NULL, cela crée une nouvelle instance. Pour ce cas particulier, l'identifiant ne sera jamais nul car il n'est utilisé que pour la modification, ne pas créer de nouveau.


3 Réponses :


-2
votes

Au lieu d'utiliser des entités persistantes, envisagez d'utiliser DTO (vous pouvez les appeler un modèle de page dans le cas des pages Web). Ils peuvent vous donner une flexibilité pour représenter des informations que vous souhaitez et le montrer au format souhaité. Mais vous devriez payer pour cela - vous ajoutez de nouvelles classes à votre système et vous devez créer un moyen de transformer des entités vers DTO et en arrière.


6 commentaires

Il n'y a aucune raison d'avoir deux couches de cartographie quand on suffit.


Je n'ai rien dit sur la couche de cartographie. DTO / VO est une couche pour décrivant ou envoi de données en fonction de l'objectif. Il ne suffit généralement pas d'avoir des entités persistantes pour tout, vous devez avoir des cours qui portent des informations spécifiquement à des fins particulières.


Assez juste, mais cela ne concerne pas vraiment la question.


Au lieu de violer Hibernate, dans la plupart des cas, il vaut mieux définir les DTO. Ce n'est pas une réponse à la question, mais plutôt une solution au problème décrit.


Je pourrais juste regarder cela. Même si cela se sent complètement inutile d'écrire des dtopes supplémentaires pour que les enfants ne soient pas touchés. Parfois, je souhaite que Hibernate n'ait jamais été inventé et que je n'étais pas obligé de l'utiliser.


Si vous travaillez avec ceci pour une année, vous comprenez à quel point cela vous aide et combien cela fait pour vous :) Cela fait vraiment beaucoup de choses que vous vous écrivez si vous avez utilisé JDBC. Donc juste profiter;)



1
votes
  1. Ne pas désactiver la récupération paresseuse dans une cartographie. Utilisez extraire des stratégies Pour le réglage de la performance.
  2. Hibernate ne retirera que les chambres d'un appartement si vous le disiez de sauvegarder / mettre à jour un appartement qui ne possède aucune pièce.

13 commentaires

Merci pour cela! 1. Je viens de mettre en œuvre une stratégie d'attraction et cela fonctionne bien. 2. Lorsque l'action de sauvegarde est appelée, toutes les chambres sont passées de l'appartement-objet. Il semble si non eccésaire de faire un autre appel à la DB pour repeupler la liste des chambres juste pour que cela ne soit pas touché lors de la persistance de l'appartement. Est-ce vraiment comment il est censé être?


Je suppose que vous essayez de créer une nouvelle instance, définissez manuellement la propriété principale de la clé, puis enregistrez-la. C'est destiné à une défaillance de différentes manières différentes. La bonne façon de mettre à jour une entité est de le charger d'abord, puis apportez-la dans une transaction.


Le point que je cherche à faire est: je veux juste mettre à jour l'appartement-objet. Cela équivaut à une déclaration DB (mise à jour de l'appartement .... etc.). Il ne faut pas nécessiter de charger tous les enfants, afin que le parent puisse être enregistré lorsque les enfants doivent rester intacts ..


Avec chargement paresseux, vous ne chargez pas tous les enfants.


Je ne sais pas ce qui me manque ici. Mais mon expérience est que lorsque le formulaire est soumis (dans Enregistrer-Action), l'appartement de méthode.Brooms () retournera NULL. Donc, afin de ne pas renvoyer NULL, je devrais d'abord faire: Appartement.setrooms (Appartementhibernateimplyl.get (apparthibernateimplyl.get (appartement).


Encore une fois, si vous parlez d'une mise à jour, la première étape appropriée consiste à charger l'appartement en utilisant Hibernate. Si vous voulez dire que immédiatement après le chargement, Apartment.Brooms () renvoie NULL, vous avez un problème dans vos mappages et de répondre à votre question, non, il n'est pas correct que vous devriez avoir à charger manuellement les chambres séparément de l'appartement. L'ensemble de l'ORM est de gérer ce type de relations pour vous.


J'ai un exemple de projet sur GitHub qui montre une utilisation de base d'une cartographie un à plusieurs hibernation. Vous pouvez le cloner avec git clone git: //github.com/zgithub.com/zzantozz/testbed tmp , puis regardez le module nommé hibernate-unidirectionnel-one-to-plusieurs-one-one-to-join-colonne ou < un href = "https://github.com/zzantozz/testbed/tree/master/hibernate-unidirectional-one-a-many-with-join-column" rel = "NOFOOL NOREFERRER"> Regardez-le sur GitHub . Il montre que la sauvegarde d'une entité mère puis de le charger chargerait également les enfants mappés.


Aha. Je pense que nous avons un malentendu mutuellement. Votre exemple est bon, je connais les bases que vous essayez de me montrer. Ce dont je parle, c'est faire une action de Struts2. Vous voyez, lorsque le formulaire est chargé, la méthode d'action édition () est exécutée et cette méthode remplit l'appartement-objet (avec des enfants). Jusqu'ici tout va bien. Ensuite, le formulaire est soumis, Save Action-Method () est exécuté et cette méthode ne rechargez pas l'objet appartement. Alors maintenant, nous avons un objet appartement sans enfants. Je pourrais recharger les enfants, puis sauver, mais cela semble inutile. Obtenez-vous ce que je dis?


Ce que je vous entends dire, c'est que votre sauvegarde crée un nouvel objet d'appartement et que vous allez l'enregistrer directement. Ma réponse est toujours la même: vous doit utiliser un objet persistant et le modifier plutôt que de la créer un nouveau et le sauver. Soit emprunter l'appartement que vous avez chargé dans Edit () et stockez-le dans la session HTTP et réutilisez-le, ou chargez-le à nouveau dans la méthode EDIT (). Peu importe que vous le fassiez dans des jambes de force ou non. Le faire comme vous le faites est contraire à la façon dont les ormes fonctionnent, et c'est mènera à plus de problèmes à l'avenir.


aha. Donc, je suppose que c'est mon lien manquant ici! Je dois prendre mon objet et le stocker dans la session HTTP pour la réutilisation. J'ai réfléchi à cela depuis des siècles, mais je n'ai pas pu trouver une réponse sur la manière de la stocker à la session. Savez-vous où trouver un tutoriel?


Vous devriez probablement lire "Sessions et transactions" et " Session ouverte en vue ". Ce dernier traite spécifiquement de "Conversations longues" . Notez cependant qu'il est beaucoup plus commun - et beaucoup plus simple - de charger à nouveau l'objet à nouveau sur la demande suivante. Je ne comprends pas pourquoi vous semblez être si dur sur cette option.


D'accord. Je me rends. Je vais recharger l'objet. :) Je suis juste utilisé pour programmer avec des procédures stockées et je n'aime pas les appels non spécifiques à la base de données.


Votre vie sera beaucoup plus simple de cette façon :) Traiter les appels de base de données aussi bon marché jusqu'à preuve contraire. Essayer de les éviter est simplement une forme d'optimisation et l'optimisation doit toujours être reportée jusqu'à ce qu'il y ait un problème de performance éprouvé.



11
votes

C'est vraiment simple. Pas besoin de repeupler vos enfants ou de créer des dto séparés.

Si vous ne voulez jamais persister les enfants, ajoutez simplement insérable = False, mise à jour = FALSE à votre annotation JOINCOLUNN. Comme ceci: xxx


2 commentaires

Merci! Juste ce que je voulais. Facile, propre et droit au point!


@ user829237: Vous réalisez que cela signifie que vous pouvez jamais ajouter une chambre à un appartement en l'ajoutant à la liste des chambres, non?