@UniqueConstraint用于可空字段

时间:2013-11-22 12:19:37

标签: mysql sql hibernate jpa unique-constraint

我有一个Product实体,namecategory组合对于每个产品都应该是唯一的。

在我的情况下,name是必需的,但category可能不存在。

Product的定义如下:

@Entity
@Table(
    uniqueConstraints=
        @UniqueConstraint(columnNames={"name", "category")
)
public class Product {

    // ...

    @NotNull
    @Size(min = 1, max = 64)
    private String name;

    @ManyToOne(fetch = FetchType.EAGER)
    private ProductCategory category;

    // ...

}

...但只有当类别不是NULL时,约束才有效。

换句话说,我不能坚持(这没关系)实体:

name="example", category=1
name="example", category=1

...同时我可以坚持(这不是我想要的)实体wihh:

name="example", category=null
name="example", category=null

所以,我的问题是 - 如何为字段组合实现唯一约束,其中一个字段可以为空(将NULL视为任何其他值)?

PS:我使用Hibernate作为JPA提供程序和MySQL数据库。

2 个答案:

答案 0 :(得分:0)

@UniqueConstraints注释应该完成工作。使用示例检查the documentation。此外,如果表是自动生成的,您可以考虑删除表,具体取决于您在persistence.xml文件中设置架构自动生成的方式。

<强>更新 当然,您必须指定两个列(而不是您所做的字段):

@UniqueConstraint(columnNames={"name", "category_id")//or check the name of the column in the db for category

更新2 因为问题实际上是在mysql中,所以可以在实体中插入其他两个持久字段:

@Column(columnName="category", insertable=false, updatable=false)//map to the same column used for your category
private Long categoryId;//I suppose it is a Long. 

@Column(columnName="categoryIdConstraint")//
private long categoryIdConstraint;//this is not nullable. If categoryId is null, then simply put 0 or -1

//and now synchronize the categoryIdConstraint field with entity listeners
//and add the @UniqueConstraint over "name" and "categoryIdConstraint" (which now cannot be null.)

答案 1 :(得分:0)

管理以避免相对容易地解决这个问题(通过应用空对象模式)。

对于任何无法轻易避免此问题的人,并且想知道如何以尽可能少的痛苦来解决这个问题 - 请看一下实现mysql trigger,它将执行考虑可以为空的列的唯一约束验证。 Here是一个很好的起点。