@UniqueConstraint 和 @Column(unique = true) 在休眠注释中
Posted
技术标签:
【中文标题】@UniqueConstraint 和 @Column(unique = true) 在休眠注释中【英文标题】:@UniqueConstraint and @Column(unique = true) in hibernate annotation 【发布时间】:2013-02-28 15:22:23 【问题描述】:@UniqueConstraint 和 @Column(unique = true) 有什么区别?
例如:
@Table(
name = "product_serial_group_mask",
uniqueConstraints = @UniqueConstraint(columnNames = "mask", "group")
)
和
@Column(unique = true)
@ManyToOne(optional = false, fetch = FetchType.EAGER)
private ProductSerialMask mask;
@Column(unique = true)
@ManyToOne(optional = false, fetch = FetchType.EAGER)
private Group group;
【问题讨论】:
注意:在 Hibernate 5.4 中,当我添加unique=true
时,方案自动更新程序没有添加索引。 @UniqueConstraint
让它出现了。可能是一个错误。
【参考方案1】:
如前所述,@Column(unique = true)
是UniqueConstraint
的快捷方式,当它只有一个字段时。
从您给出的示例来看,两者之间存在巨大差异。
@Column(unique = true)
@ManyToOne(optional = false, fetch = FetchType.EAGER)
private ProductSerialMask mask;
@Column(unique = true)
@ManyToOne(optional = false, fetch = FetchType.EAGER)
private Group group;
此代码意味着mask
和group
必须是唯一的,但要分开。这意味着,例如,如果您有一条 mask.id = 1 的记录并尝试插入另一条 mask.id = 1 的记录,您将得到一个错误,因为该列应该具有唯一值。这同样适用于团体。
另一方面,
@Table(
name = "product_serial_group_mask",
uniqueConstraints = @UniqueConstraint(columnNames = "mask", "group")
)
表示 mask + group 组合的值应该是唯一的。这意味着您可以拥有例如 mask.id = 1 和 group.id = 1 的记录,如果您尝试使用 插入另一条记录mask.id = 1 和 group.id = 2,它会成功插入,而第一种情况则不会。
如果你想让掩码和组分别唯一并且在类级别上是唯一的,你必须编写如下代码:
@Table(
name = "product_serial_group_mask",
uniqueConstraints =
@UniqueConstraint(columnNames = "mask"),
@UniqueConstraint(columnNames = "group")
)
这与第一个代码块的效果相同。
【讨论】:
创建唯一约束后,我是否可以在我的 JPA 存储库中按名称引用约束来进行查询? @jDub9 不能查询索引。您可以在一个查询中查询掩码和分组列,它会使用该索引来加快处理速度(如果幸运的话),但您不能简单地查询索引。 请注意,尽管 columnNames 必须是数据库中的实际名称。如果使用默认命名策略,则应为mask_id
和group_id
。【参考方案2】:
来自 Java EE 文档:
public abstract boolean unique
(可选)属性是否为唯一键。这是一个快捷方式 表级别的 UniqueConstraint 注释,对于唯一键时很有用 约束只是一个字段。除任何约束外,此约束均适用 由主键映射和在表级别指定的约束所包含。
见doc
【讨论】:
所以当我使用这个代码时:@Column(unique = true) @ManyToOne(optional = false, fetch = FetchType.EAGER) private ProductSerialMask mask; @Column(unique = true) @ManyToOne(optional = false, fetch = FetchType.EAGER) 私有组组;我有两个索引,但是当使用其他方式时,我有一个索引,它是两列的组合?【参考方案3】:除了波阿斯的回答......
@UniqueConstraint
允许您命名约束,而@Column(unique = true)
生成一个随机名称(例如UK_3u5h7y36qqa13y3mauc5xxayq
)。
有时了解约束与哪个表相关联会很有帮助。例如:
@Table(
name = "product_serial_group_mask",
uniqueConstraints =
@UniqueConstraint(
columnNames = "mask", "group",
name="uk_product_serial_group_mask"
)
)
【讨论】:
【参考方案4】:除了@Boaz 和@vegemite4me 的回答......
通过实现ImplicitNamingStrategy
,您可以创建自动命名约束的规则。请注意,您在 Hibernate 初始化期间将命名策略添加到 metadataBuilder
:
metadataBuilder.applyImplicitNamingStrategy(new MyImplicitNamingStrategy());
它适用于 @UniqueConstraint
,但不适用于 @Column(unique = true)
,它总是生成一个随机名称(例如 UK_3u5h7y36qqa13y3mauc5xxayq)。
有解决此问题的错误报告,所以如果可以,请在那里投票以实现此问题。 这里: https://hibernate.atlassian.net/browse/HHH-11586
谢谢。
【讨论】:
以上是关于@UniqueConstraint 和 @Column(unique = true) 在休眠注释中的主要内容,如果未能解决你的问题,请参考以下文章
Symfony UniqueEntity vs UniqueConstraint vs unique=true