如何使用JPA中的WHERE子句注释唯一约束

时间:2012-08-19 10:33:11

标签: postgresql jpa unique-constraint

我需要在PostgreSQL中使用这些独特的约束

CREATE UNIQUE INDEX favorites_3col_uni_idx
ON favorites (user_id, menu_id, recipe_id)
WHERE menu_id IS NOT NULL;

CREATE UNIQUE INDEX favorites_2col_uni_idx
ON favorites (user_id, recipe_id)
WHERE menu_id IS NULL;

我在JPA中注释的第一个:

@Table(uniqueConstraints= {
@UniqueConstraint(name="favorites_3col_uni_idx", columnNames = {"user_id", "menu_id", "recipe_id"})
})

但是,¿可以在JPA中注释第二个唯一索引吗?

THX。

1 个答案:

答案 0 :(得分:4)

您似乎想要使用JPA约束定义创建partial indexesCREATE INDEX ... ON ... WHERE)。

这些是特定于PostgreSQL的,并且未由JPA指定。您将需要使用本机语法来创建它们。我不相信JPA提供索引定义的任何功能。

您不能为此目的使用唯一约束,因为唯一的部分索引不是唯一约束。在PostgreSQL中无法使用CONSTRAINT constraint_name UNIQUE(columns)创建部分唯一索引。它只是一个实现细节,PostgreSQL为唯一约束创建了一个唯一索引。

请参阅:

某些JPA提供程序提供特定于该JPA提供程序的扩展注释,这些扩展注释添加了用于运行本机DDL脚本,定义带有annoations的索引等功能。由于您没有提到您正在使用哪个JPA提供程序,因此无法告诉您更多信息。这是documentation for EclipseLink index DDL;如果您使用的是Hibernate,OpenJPA或EclipseLink之外的其他内容,

JPA标准解决方法是通过查询pg_catalog.pg_index来检查启动期间是否存在这些索引。如果找不到它们,请使用EntityManager本机查询发送相应的本机SQL CREATE UNIQUE INDEX命令。如果您使用EJB3.1,@Startup @Singleton bean对此类任务很有用。有关pg_catalog.pg_index的结构,请参阅PostgreSQL文档。要检查是否存在给定名称的索引,请运行:

SELECT EXISTS(
    SELECT 1 
    FROM pg_index 
    WHERE indexrelid = 'public.indexname'::regclass
);

请注意,上述查询无法验证它是您期望的索引,但您可以通过一些额外的检查来执行此操作。只需在创建索引后检查pg_index的内容,以便知道要测试的内容。我不建议您尝试检查indpred的任何特定值;只是确保它不是空的。