2011-09-30 2 views
1

J'ai un problème avec Hibernate et l'application de membres de données uniques lors de l'insertion.Hibernate: appliquer des membres de données uniques

Voici mes objets abrégés Entité:

Flux de travail:

@Entity 
public class Workflow { 

    private long wfId; 

    private Set<Service> services; 

    /** Getter/Setter for wfId */ 
    ... 

    @OneToMany(cascade = CascadeType.ALL) 
    @JoinTable(name = "workflow_services", 
     joinColumns = @JoinColumn(name = "workflow_id"), 
     inverseJoinColumns = @JoinColumn(name = "service_id")) 
    public Set<Service> getServices() { 
     return services; 
    } 

Service:

@Entity 
public class Service { 

    private long serviceId; 
    private String serviceName; 

    /** Getter/Setter for serviceId */ 
    ... 

    @Column(unique=true,nullable=false) 
    public String getServiceName() { 
    return serviceName; 
    } 

    @OneToMany(cascade = CascadeType.ALL) 
    @JoinTable(name = "service_operations", 
     joinColumns = { @JoinColumn(name = "serviceId") }, 
     inverseJoinColumns = { @JoinColumn(name = "operationId") }) 
    public Set<Operation> getOperations() { 
     return operations; 
    } 

Opération:

@Entity 
public class Operation { 

    private long operationId; 
    private String operationName; 

    /** Getter/Setter for operationId */ 

    @Column(unique=true,nullable=false) 
    public String getOperationName() { 
     return operationName; 
    } 

Mon numéro:

Bien que j'aie indiqué dans chaque objet ce qui est SUPPOSÉ pour être unique, il n'est pas appliqué.

Dans mon objet Workflow, je gère un ensemble de services. Chaque service maintient une liste des opérations. Quand un flux de travail est enregistré dans la base de données, j'en ai besoin pour vérifier si les services et les opérations qu'il utilise sont déjà dans la base de données, si oui, s'associez-vous à ces lignes.

Actuellement, je reçois des reprises dans mes tables Services et Opérations.

J'ai essayé d'utiliser l'annotation: @Table (uniqueConstraints)

mais ont eu zéro chance avec elle.

Toute aide serait grandement appréciée

+0

Quelle base de données et quel dialecte utilisez-vous? Comment avez-vous créé les tables dans votre base de données? hbm2ddl? Pouvez-vous montrer les requêtes utilisées pour générer votre table? Je ne pense pas que Hibernate vérifie jamais l'unicité elle-même, mais elle devrait générer des tables avec les contraintes uniques appropriées dans votre base de données. –

Répondre

0

Les attributs uniques ou uniqueConstraints ne sont pas utilisés pour faire respecter l'unicité dans la base de données, mais créer le DDL correct si vous générez de mise en veille prolongée (et pour la documentation aussi, mais ce peut soutenir).

Si vous déclarez quelque chose d'unique dans Hibernate, vous devez le déclarer également dans la BD, en ajoutant une contrainte. En prenant cela à l'extrême, vous pouvez créer un mappage dans lequel le PK n'est pas unique dans la base de données, et Hibernate lèvera une exception quand il essayera de charger un élément en appelant Session.load, et en trouvant soudainement qu'il y a sont 2 articles.

0

À l'intérieur de mon objet Workflow, je gère un ensemble de services. Chaque service maintient une liste des opérations. Quand un flux de travail est enregistré dans la base de données, j'en ai besoin pour vérifier si les services et les opérations qu'il utilise sont déjà dans la base de données, si oui, s'associez-vous à ces lignes.

Je pense que vous demandez Hibernate pour détecter des objets en double lorsque vous les ajoutez à l'ensemble, oui? En d'autres termes, lorsque vous placez un objet dans l'ensemble, vous voulez que Hibernate recherche une version persistante de cet objet et l'utilise. Cependant, ce n'est pas comme ça que fonctionne Hibernate. Si vous voulez "réutiliser" un objet, vous devez le rechercher vous-même et ensuite l'utiliser. Hibernate ne fait pas ça.

Je suggère d'avoir une méthode d'assistance sur un objet de type DAO qui prend l'objet parent et l'objet enfant, puis effectue la recherche et le réglage pour vous.

+0

C'est ce sur quoi je travaille en ce moment. Mon problème maintenant est que Hibernate jette une erreur en essayant de rajouter un objet et j'obtiens une erreur de 'clé en double'. J'utilise 'session.saveOrUpdate (workflow)' ce qui est sympa, mais je crois que c'est seulement pour le workflow lui-même et non pour ses sous-éléments. c'est-à-dire service et opération. ANy pensées? –

+0

Il semble que vous définissiez des objets détachés dans l'objet Workflow. Vous devez récupérer les sous-objets (par requête, ID, etc.) puis * dans la même session * les ajouter à leur ensemble correspondant et enregistrer l'objet parent. Tant que votre cascade est correctement configurée, Hibernate devrait juste "faire la bonne chose" avec les sous-objets. Cela a-t-il du sens? – Mac

Questions connexes