Java hibernate唯一约束

Java hibernate唯一约束,java,hibernate,Java,Hibernate,我面临以下问题 请看上面链接上的评论:) 在解决这个问题时,我现在有一个问题,关于惟一约束在hibernate中是如何实现的,我开始相信它会触发一个select查询(我对此不确定),然后“某种方式”执行验证 我不太相信这样的解释,Hibernate在该列上创建了一个“唯一”索引,然后是数据库强制执行唯一性 例如,如果您有一个类: @Entity @Cache(usage = CacheConcurrencyStrategy.READ_WRITE) public class UserEmailA

我面临以下问题

请看上面链接上的评论:)

在解决这个问题时,我现在有一个问题,关于惟一约束在hibernate中是如何实现的,我开始相信它会触发一个select查询(我对此不确定),然后“某种方式”执行验证

我不太相信这样的解释,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,想法都是一样的)

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,想法都是一样的)


我试图复制这种行为,我使用Grails1.3.7,发现它是可复制的

class Child {
    String name
    static constraints = { name(unique:true) }
}
已创建表
创建表“child”(
`id`BIGINT(20)非空自动增量,
`name`VARCHAR(255)不为空,
主键(`id`),
唯一键`name`(`name`)
)
针对 child.save()

Hibernate:选择此id为id0\u 0,此版本为version0\u 0,此创建者为created3\u 0\u 0,此日期为date4\u 0\u 0,此上次更新为last5\u 0\u,此名称为name0\u,此更新者为updated 7\u 0\u 0\u从该子级开始,其中此名称=?
Hibernate:插入子(版本、创建人、创建日期、上次更新、名称、更新人)值(?、、、、、、、?)
我认为hibernate触发上述查询的原因是为了检查唯一约束,如果您试图执行更新,那么此查询将导致内存中具有相同标识符的另一个对象,这可能导致UnuniqueObjectException

我认为这是hibernate而不是grails,在java/hibernate中没有仔细检查过这一点


感谢

我尝试复制这个行为,我使用Grails1.3.7并发现它是可复制的

class Child {
    String name
    static constraints = { name(unique:true) }
}
已创建表
创建表“child”(
`id`BIGINT(20)非空自动增量,
`name`VARCHAR(255)不为空,
主键(`id`),
唯一键`name`(`name`)
)
针对 child.save()

Hibernate:选择此id为id0\u 0,此版本为version0\u 0,此创建者为created3\u 0\u 0,此日期为date4\u 0\u 0,此上次更新为last5\u 0\u,此名称为name0\u,此更新者为updated 7\u 0\u 0\u从该子级开始,其中此名称=?
Hibernate:插入子(版本、创建人、创建日期、上次更新、名称、更新人)值(?、、、、、、、?)
我认为hibernate触发上述查询的原因是为了检查唯一约束,如果您试图执行更新,那么此查询将导致内存中具有相同标识符的另一个对象,这可能导致UnuniqueObjectException

我认为这是hibernate而不是grails,在java/hibernate中没有仔细检查过这一点


谢谢

我也这么想,但是如果你看一下给定链接上的评论,你会发现当我对…有唯一的限制时。。hibernate在session.save(entity)上启动了一个查询,当我删除该约束时,它没有启动该查询,对此有什么想法吗?我尝试在本地重新创建该行为,但没有任何运气,抱歉:(即使有唯一的约束,它也会直接插入(用于新实体)或更新(当…更新时)我也这么想,但是如果你看一下给定链接上的注释,你会发现当我对…有唯一约束时,hibernate正在对session.save(entity)启动一个查询,当我删除该约束时它没有启动该查询,对此有什么想法吗?我已经尝试在本地重新创建该行为,但我没有任何运气,对不起:(即使有一个唯一的约束,它也会直接插入(用于新实体)或更新(当…更新时)。任何人都可以确认这种行为是否特定于grails,我在使用@UniqueConstraints时没有看到类似的行为。它是特定于grails的。这也是非常值得怀疑的(唯一性可能在SQL检查和tx提交之间同时发生变化)有人能确认此行为是否特定于grails吗,我在使用@UniqueConstraints时没有看到类似的行为它特定于grails。而且也非常可疑(唯一性可能在SQL检查和tx提交之间同时发生变化)请包括“下面的问题”的要点,这样这篇文章就独立了。请包括“下面的问题”的要点,这样这篇文章就独立了。