休眠注释中的@UniqueConstraint和@Column(unique = true)


104

@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;

2
注意:在Hibernate 5.4中,当我添加时unique=true,方案自动更新程序未添加该索引。@UniqueConstraint使它出现。可能是一个错误。
OndraŽižka'17

Answers:


147

如前所述,@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;

此代码暗示两者maskgroup必须是唯一的,但必须分别。这意味着,例如,如果您有一个mask.id = 1的记录,并尝试插入另一个mask.id = 1的记录,则会出现错误,因为该列应具有唯一值。同样适用于组。

另一方面,

@Table(
   name = "product_serial_group_mask", 
   uniqueConstraints = {@UniqueConstraint(columnNames = {"mask", "group"})}
)

表示mask + group group的值应该唯一。这意味着您可以拥有例如mask.id = 1group.id = 1的记录,如果您尝试插入另一个mask.id = 1group.id = 2的记录,则将其插入成功,而在第一种情况下则不会。

如果要使掩码和组在类级别分别和唯一,则必须编写如下代码:

@Table(
        name = "product_serial_group_mask",
        uniqueConstraints = {
                @UniqueConstraint(columnNames = "mask"),
                @UniqueConstraint(columnNames = "group")
        }
)

这与第一个代码块具有相同的效果。


创建唯一约束后,是否可以在我的JPA存储库中按名称引用约束以进行查询?
jDub9

@ jDub9您无法查询索引。您可以在一个查询中查询mask和group列,它将使用该索引进行更快的处理(如果幸运的话),但是您不能简单地查询一个索引。
达利博尔·菲卢斯

请注意,尽管columnNames必须是数据库中的实际名称。如果使用默认命名策略mask_idgroup_id则应该是。
体外

27

从Java EE文档中:

public abstract boolean unique

(可选)属性是否为唯一键。这是表级别的UniqueConstraint批注的快捷方式,对于唯一键约束仅是单个字段的情况很有用。除了主键映射所引起的任何约束以及在表级别指定的约束之外,该约束也适用。

文件


所以当我使用以下代码时:@Column(unique = true)@ManyToOne(optional = false,fetch = FetchType.EAGER)private ProductSerialMask mask; @Column(unique = true)@ManyToOne(可选= false,fetch = FetchType.EAGER)私有组组;我有两个索引,但是当以其他方式使用时,我有一个索引是两列的组合?
navid_gh 2013年

22

除了波阿斯的答案....

@UniqueConstraint允许您为约束命名,同时@Column(unique = true)生成一个随机名称(例如UK_3u5h7y36qqa13y3mauc5xxayq)。

有时了解约束与哪个表可能会有帮助。例如:

@Table(
   name = "product_serial_group_mask", 
   uniqueConstraints = {
      @UniqueConstraint(
          columnNames = {"mask", "group"},
          name="uk_product_serial_group_mask"
      )
   }
)

5

除了@Boaz和@ vegemite4me的答案...。

通过实施,ImplicitNamingStrategy您可以创建用于自动命名约束的规则。请注意,您metadataBuilder在Hibernate的初始化期间将命名策略添加到:

metadataBuilder.applyImplicitNamingStrategy(new MyImplicitNamingStrategy());

它适用于@UniqueConstraint,但不适用于@Column(unique = true),它始终生成一个随机名称(例如UK_3u5h7y36qqa13y3mauc5xxayq)。

有一个错误报告可以解决此问题,因此,如果可以,请在此处进行投票以实现此问题此处:https//hibernate.atlassian.net/browse/HHH-11586

谢谢。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.