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)
)
Hibernate creates a "unique" index on that column, and it's the database that then enforces the uniquness.
For example, if you have a class:
@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 creates a table like so: (for PostgreSQL, but the idea is the same for pretty much all 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)
)
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 (?, ?, ?, ?, ?, ?)
I tried to replicate this behavior , I using using grails 1.3.7 and found it to be reproducible
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`)
)
Queries fired on 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 (?, ?, ?, ?, ?, ?)
The reason i think i hibernate fires the above query is to check the unique constraint, And in case you are trying to perform an update then this query will result in having another object with the same identifier in memory, which could the lead to nonuniqueobjectexception.
I thinking this is hibernate and not grails, have not double checked this in java/hibernate.
发布评论
评论(2)
Hibernate 在该列上创建一个“唯一”索引,然后由数据库强制执行唯一性。
例如,如果你有一个类:
Hibernate 创建一个像这样的表:(对于 PostgreSQL,但对于几乎所有 RDBMS 的想法都是相同的)
Hibernate creates a "unique" index on that column, and it's the database that then enforces the uniquness.
For example, if you have a class:
Hibernate creates a table like so: (for PostgreSQL, but the idea is the same for pretty much all RDBMS)
我尝试复制此行为,我使用 grails 1.3.7 并发现它是可重现的
查询触发
child.save()
我认为我休眠触发上述查询的原因是检查唯一约束,如果您尝试执行更新,那么此查询将导致内存中具有另一个具有相同标识符的对象,这可能导致非唯一对象异常。
我认为这是休眠而不是 grails,没有在 java/hibernate 中仔细检查这一点。
谢谢
I tried to replicate this behavior , I using using grails 1.3.7 and found it to be reproducible
Queries fired on
child.save()
The reason i think i hibernate fires the above query is to check the unique constraint, And in case you are trying to perform an update then this query will result in having another object with the same identifier in memory, which could the lead to nonuniqueobjectexception.
I thinking this is hibernate and not grails, have not double checked this in java/hibernate.
Thanks