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

9

我需要在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中是否有可能注释第二个唯一索引呢?

谢谢。

1个回答

8

您似乎想使用JPA约束定义创建部分索引CREATE INDEX ... ON ... WHERE),这些是相当特定于PostgreSQL的,并且不由JPA指定。您需要使用本机语法来创建它们。我认为JPA没有提供任何索引定义功能。

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

请参见:

一些 JPA 提供者提供了特定于该 JPA 提供者的扩展注释,以添加运行本机 DDL 脚本、使用注释定义索引等功能。由于您没有提到您正在使用哪个 JPA 提供者,我无法告诉您更多信息。这是EclipseLink 索引 DDL 文档;如果您使用的不是 EclipseLink,则此方法将无法正常工作。
JPA 的标准解决方法是在启动时通过查询 pg_catalog.pg_index 来检查这些索引是否存在。如果找不到它们,请使用 EntityManager 本地查询发送适当的本机 SQL CREATE UNIQUE INDEX 命令。如果您使用 EJB3.1,则 @Startup @Singleton bean 对于这种任务非常有用。请参阅 PostgreSQL 文档以获取 pg_catalog.pg_index 的结构。要仅检查给定名称的索引是否存在,请运行:
SELECT EXISTS(
    SELECT 1 
    FROM pg_index 
    WHERE indexrelid = 'public.indexname'::regclass
);

请注意,上述查询并未验证它是否是您所期望的索引,但您可以通过一些额外的检查来实现。只需在创建索引后检查pg_index的内容,以便您知道要进行测试的内容。我不建议尝试检查indpred的任何特定值;只需确保它不为null即可。

太好了!感谢您详细的解释,我会阅读相关资料并尝试以编程方式实现。 - Jose.OC

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接