【发布时间】:2011-05-15 13:23:39
【问题描述】:
我遇到了以下问题 problem
附:看看上面链接上的 cmets :)
在解决它的同时,我现在有一个关于如何在休眠中实现唯一约束的问题,我开始相信它会触发一个选择查询(我不确定这一点),然后“某种方式”执行验证。
我不太相信这个解释
【问题讨论】:
-
请包括“下面的问题问题”的亮点,以便这篇文章是独立的。
我遇到了以下问题 problem
附:看看上面链接上的 cmets :)
在解决它的同时,我现在有一个关于如何在休眠中实现唯一约束的问题,我开始相信它会触发一个选择查询(我不确定这一点),然后“某种方式”执行验证。
我不太相信这个解释
【问题讨论】:
Hibernate 在该列上创建一个“唯一”索引,然后由数据库强制执行唯一性。
例如,如果你有一个班级:
@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;
}
Hibernate 像这样创建一个表:(对于 PostgreSQL,但几乎所有 RDBMS 的想法都是一样的)
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)
)
【讨论】:
我试图复制这种行为,我使用 grails 1.3.7 并发现它是可重现的
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`)
)
触发的查询 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 (?, ?, ?, ?, ?, ?)
我认为我休眠触发上述查询的原因是检查唯一约束,如果您尝试执行更新,那么此查询将导致内存中有另一个具有相同标识符的对象,这可能导致到非唯一对象异常。
我认为这是休眠而不是 grails,没有在 java/hibernate 中仔细检查过。
谢谢
【讨论】: