2011-05-15 4 views
1

j'ai été confronté au problème ci-dessous problemmise en veille prolongée contrainte unique

P: S Regardez les commnets :) sur le lien ci-dessus

Et tout en résolvant, je maintenant une question sur la façon dont la contrainte unique est implémentée dans hibernate, j'ai commencé à croire qu'elle déclenche une requête select (je ne suis pas sûr de ça), et puis "comment" effectue la validation.

Je ne suis pas très convaincu par l'explication

Répondre

4

Mise en veille prolongée crée un index « unique » sur cette colonne, et il est la base de données qui applique alors le uniquness.

Par exemple, si vous avez une classe:

@Entity 
@Cache(usage = CacheConcurrencyStrategy.READ_WRITE) 
public class UserEmailAddressEntity { 
    @Id 
    @Basic(optional = false) 
    @GeneratedValue(strategy = GenerationType.AUTO) 
    private Long id; 

    @Basic(optional = false) 
    private boolean primaryEmail; 

    @ManyToOne(optional = false) 
    private UserEntity user; 

    @NaturalId // this means the email column must be unique 
    @Basic(optional = false) 
    private String email; 

    @Basic(optional = false) 
    private String token; 

    @Basic(optional = false) 
    private boolean verified; 
} 

Mise en veille prolongée crée une table comme ceci: (pour PostgreSQL, mais l'idée est la même pour à peu près tous les SGBDR)

CREATE TABLE useremailaddressentity 
(
    id bigint NOT NULL, 
    email character varying(255) NOT NULL, 
    primaryemail boolean NOT NULL, 
    token character varying(255) NOT NULL, 
    verified boolean NOT NULL, 
    user_id bigint NOT NULL, 
    CONSTRAINT useremailaddressentity_pkey PRIMARY KEY (id), 
    CONSTRAINT fk279a5e06c843ec30 FOREIGN KEY (user_id) 
     REFERENCES userentity (id) MATCH SIMPLE 
     ON UPDATE NO ACTION ON DELETE NO ACTION, 

    -- note the `UNIQUE` here: 
    CONSTRAINT useremailaddressentity_email_key UNIQUE (email) 
) 
+0

Je pensais tout autant, si vous regardez les commentaires sur le lien donné, vous verrez que quand j'avais la contrainte unique .. Mise en veille prolongée a été une requête sur des tirs session.save (entité), qu'il n'a pas tiré quand j'ai enlevé la contrainte, des pensées sur cela? – Sudarshan

+0

J'ai essayé de recréer ce comportement localement, mais je n'ai pas eu de chance, désolé :(Même avec une contrainte unique, il fait une insertion droite (pour les nouvelles entités) ou une mise à jour (quand ... mise à jour) – wmacura

0

J'ai essayé de reproduire ce comportement, je l'aide à l'aide Grails 1.3.7 et trouvé reproductible

class Child { 
String name 
static constraints = { name(unique:true) } 

}

table created 
CREATE TABLE `child` (
    `id` BIGINT(20) NOT NULL AUTO_INCREMENT, 
    `name` VARCHAR(255) NOT NULL, 
    PRIMARY KEY (`id`), 
    UNIQUE KEY `name` (`name`) 
) 

requêtes ont tiré sur child.save()

Hibernate: select this_.id as id0_0_, this_.version as version0_0_, this_.created_by as created3_0_0_, this_.date_created as date4_0_0_, this_.last_updated as last5_0_0_, this_.name as name0_0_, this_.updated_by as updated7_0_0_ from child this_ where this_.name=? 
Hibernate: insert into child (version, created_by, date_created, last_updated, name, updated_by) values (?, ?, ?, ?, ?, ?) 

La raison pour laquelle je pense que je hiverne les feux de la requête ci-dessus est de vérifier la contrainte unique, et si vous essayez d'effectuer une mise à jour alors cette requête aboutira à avoir un autre objet avec le même identifiant en mémoire, ce qui pourrait conduire à une nonuniqueobjectexception. Je pense que c'est hibernate et pas grails, je n'ai pas vérifié cela en java/hibernate.

Merci

+0

Quelqu'un confirme si ce comportement est spécifique aux grails, je ne vois pas de comportement similaire lors de l'utilisation de @UniqueConstraints – Sudarshan

+2

Il est spécifique aux Grails et très discutable aussi (l'unicité peut changer simultanément entre la vérification SQL et la validation tx) – Vincent

Questions connexes