2017-07-18 2 views
1

J'implémente la relation un à un (un employé < -> un mobile) en hibernation comme suit. Ce code fonctionne bien, mais comme il s'agit d'une relation un à un, assigner le même numéro de mobile à emp1 et emp2 aurait créé un problème (cela viole la relation) mais le code accepte et ajoute 2 emps avec le même mobile. Pourquoi hiberner est-il une relation un à un comme < -> beaucoup d'employés? Mon code: @EntityRelation un à un en mode hibernation

public class Employee { 
    @Id @GeneratedValue(strategy=GenerationType.AUTO) 
    private int id; 
    private String name; 
    @OneToOne 
    private Mobile mobile; 
    //...rest of the code 
} 
@Entity 
public class Mobile { 
    @Id @GeneratedValue 
    private int id; 
    private long number; 
    //...rest of the code 
} 
Test Client main(...){ 
    Mobile mobile = new Mobile(9999999999L); 
    Employee emp1 = new Employee("Raja"); 
    Employee emp2 = new Employee("Raja"); 
    emp1.setMobile(mobile); 
    emp2.setMobile(mobile);// VIOLATING 1-1 RELATIONSHIP 
    //...REST OF THE COMMON CODE 
    session.save(mobile); 
    session.save(emp1); 
    session.save(emp2); 
    session.getTransaction().commit(); 
} 

BASE DE DONNÉES Combine EMP RECORDS AVEC LE NUMÉRO MOBILE MÊME (1-1 INFRACTION)

+0

Utilisez-vous la propriété hibernate 'hibernate.hbm2ddl.auto' pour générer vos tables? hibernate ajoute automatiquement la contrainte d'unicité quand elle est responsable de la création des tables sinon il faut l'ajouter manuellement. –

+0

duplicata possible de https://stackoverflow.com/questions/8968294/why-onetoone-is-allowing-duplicate-associations –

+0

Oui, ceci est similaire à la question dans le lien de commentaire. Toutes mes excuses pour la répétition –

Répondre

0

Pour une à une relation, vous devez toujours vous assurer que vous avez une expérience unique contrainte sur votre base de données (générée par hibernate ou créée manuellement).

Hibernate ne le vérifiera pas car il devra collecter des données supplémentaires à chaque fois pour effectuer le contrôle. La base de données peut le faire plus efficacement. Pour faire la vérification, Hibernate devrait faire une requête supplémentaire. Et si la base de données est configurée correctement cette requête supplémentaire coûterait du temps et des ressources sans aucun gain.

Si vous n'avez pas de contraintes uniques et que vous définissez la relation bidirectionnelle, vous pouvez avoir encore plus de problèmes. Hibernate sauvegardera les enregistrements en conflit sans se plaindre comme vous l'avez déjà découvert. Et il deviendrait impossible pour Hibernate d'utiliser la relation à partir de l'objet de l'autre côté (obtenir l'employé via le mobile dans votre cas). Si mobile est configuré pour obtenir son employé avec impatience, il deviendrait impossible de mettre le mobile en mémoire après que les deux employés ont été enregistrés.

+0

Merci Stefan pour l'avoir bien expliqué. Alors dites-moi si je l'ai bien compris - "Ce n'est pas la responsabilité de Hibernates de prendre soin de un/plusieurs à un/plusieurs, cela doit être à travers les relations des objets du modèle et c'est juste une entrée fournie pour hiberner accordé et optimiser sa mise en œuvre ". avant de vous obtenir une bonne explication, j'ai également essayé de suivre. –

+0

désolé pour un commentaire incomplet plus tôt. - Ajout de la référence de l'employé au côté mobile avec l'annotation @OneToOne pour le rendre bidirectionnel. résultant dans les deux tables avec les autres clés étrangères. Le code fixe peut être foiré en affectant emp1, emp2 au même mobile (bien que la mauvaise implémentation hib soit ignorée) –

+0

Il est hiberné de mapper correctement votre modèle d'objet à un schéma de base de données. La cohérence des données dans votre base de données est une chose différente. –