0
votes

Comment ajouter des valeurs à de nombreux côtés dans une botte de ressort relationnelle

J'ai des tables marchand et d'adresses. Un marchand peut avoir une adresse multiple et une adresse a un commerçant (un à de nombreuses relations) .Quand Ajouter une valeur marchande avec l'adresse, je reçois cette erreur. Comment résoudre cette erreur? C'est l'erreur.

public Merchant saveMerchant(Merchant merchant) {
       merchant = merchantRepository.save(merchant);
       return merchant;
    }


3 commentaires

Vous n'avez pas posté la trace complète de la pile de l'exception, mais je suppose que vous avez une contrainte non nulle sur Adresse.Merchanant_ID, et que votre code ne définit jamais l'adresse.Méricher à une valeur non nulle avant d'insérer le commerçant et Ses adresses, hibernate stocke NULL dans Merchant_ID, entraînant ainsi la violation de la contrainte.


@Jbnizet Lorsque j'ajoute un marchand en même temps, je souhaite ajouter les adresses à cet ID de marchand. Avez-vous une solution?


Oui. Définissez le champ marchand des adresses: marchand.getaddresses (). Foreach (adresse -> adresse.setmerchange (marchand)) .


3 Réponses :


0
votes

Il dit que vous avez une erreur de violation de contrainte, ce qui signifie que vous aurez peut-être défini l'une de la variable de l'entité pour ne pas être NULL, et vous essayez de sauvegarder une valeur null.


2 commentaires

Ici l'identifiant marchand n'est pas définie. Je sais ce point, mais mon scénario lors de l'addition de marchand en même temps veut ajouter une table d'adresses avec ID du commerçant.


Pourquoi ne pas avoir d'abord d'abord les adresses, enregistrez-les dans la table d'adresses, puis utilisez marchand.getaddresses.set (adresses)



1
votes

i votre modèle marchand, vous définissez cascade = {cascadetype.all} pour l'attribut Adresses. Cela signifie que pour ce cas si vous souhaitez persister un objet marchand avec des adresses, le Hibernate vérifiera si ces adresses existent déjà; Sinon, cela les créera auparavant. Mais dans votre modèle d'adresse, vous définissez nullabel = false sur l'attribut marchand que signifie que l'objet d'adresse ne peut pas persister sans le commerçant existant. Ensuite, lorsque l'hibernate Essayez de persister le marchand et de trouver une adresse qui n'est pas encore persisté, il tente de persister cette adresse précédente, il trouve également un objet marchand nulle puis lancer cette exception org.ibernate. Exception.ConstruitsViolationExceptionException .

Vous devez choisir l'une de ces propositions:

  • Supprimer nullable = false contrainte dans l'attribut marchand sur le modèle d'adresse. Si vous faites cela, l'adresse sera persistée sans marchand. Ensuite, lorsque vous persistez marchand hibernate mettra à jour l'adresse.

  • Changement cascade = {cascadetype.Alt} à tous les autres cascade sauf persist dans les adresses attributs du modèle marchand. Si vous faites cela, vous devriez persister le marchand avant vous-même, puis persistez l'adresse avec le commerçant existant.


6 commentaires

Pouvez-vous changer dans mon code parce que je ne pouvais pas comprendre votre réponse.


Essayez ceci @JOINCOLUMN (NAME = "MARCHANT_ID") au lieu de @JOINCOLUMN (NAME = "MARCHANT_ID", NULLABLE = FALSE)


{"Timestamp": 1554885216731, "Statut": 500, "Erreur": "Erreur de serveur interne", "Message": "Impossible d'exécuter la déclaration; SQL [N / A]; Contrainte [NULL]; une exception imbriquée est org. hibernate.exception.constraintServiolationException: impossible d'exécuter la déclaration "," Path ":" / Merchant-Service / Save-Merchant "}


dans le journal de démarrage du printemps: java.sql.sqlintegrityConstraintServiolationException: la colonne 'Merchant_id' ne peut pas être null


Je suis sûr que dans la table d'adresses, le champ Merchant_ID n'a pas de contrainte null. Vous devez également le supprimer.


J'ai résolu ce problème. J'ai ajouté cette réponse ici.



1
votes

dans la table Merceuse:

public Merchant saveMerchant(Merchant merchant) {
       merchant = merchantRepository.save(merchant);
        Merchant finalMerchant = merchant;
        merchant.getAddresses().forEach(address -> {
           address.setMerchant(finalMerchant);
           addressRepository.save(address);
       });
       return merchant;
    }


10 commentaires

Vous ne devriez pas créer un nouveau marchand pour chaque adresse. Vous devez définir le marchand unique dans chaque adresse.


@Jbnizet ici je fais comme ça.


Je donne un identifiant marchand à toutes les discours.


Toutes les adresses sont censées avoir le même marchand. Alors, pourquoi créez-vous un marchand nouveau pour chaque adresse. Il suffit de définir le même objet marchand sur chaque adresse.


C'est un objet négatif vide et après avoir ajouté un marchand, je reçois cet identifiant et définir l'ID sur l'objet marchand et connecté à l'adresse.SetMerchant. Ça marche pour moi. Si vous avez des doutes, je vais envoyer ma sortie.


D'abord, j'ajoute un marchand alors j'utilise cet identifiant vers chaque création d'adresse.


Cela fonctionne, mais il est inutilement compliqué et inefficace, et mal, car je répète, toutes les adresses devraient avoir le même Merchant: celui que vous économisez au début de la méthode.


@Jbnizet j'ai mis à jour cette réponse s'il vous plaît pouvez-vous vérifier?


C'est beaucoup mieux. Vous pouvez le rendre encore plus simple en réglant le marchand sur les adresses avant d'enregistrer le commerçant et en supprimant l'appel à adressesRepository.Save (adresse), puisque vous avez une cascade et que vous enregistrez le marchand enregistrerait ainsi les adresses.


Laissez-nous Continuez cette discussion en chat .