8

我需要在 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 中注释第二个唯一索引吗?

谢谢。

4

1 回答 1

8

您似乎想要使用 JPA 约束定义创建部分索引( )。CREATE INDEX ... ON ... WHERE

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

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

看:

Some JPA providers offer extension annotations specific to that JPA provider that add features for running native DDL scripts, defining indexes with annoations, etc. Since you haven't mentioned which JPA provider you are using I can't tell you more. Here's the documentation for EclipseLink index DDL; this will not work if you are using Hibernate, OpenJPA, or something other than EclipseLink.

A JPA standard workaround is to check for the presence of those indexes during startup by querying pg_catalog.pg_index. If you don't find them, use an EntityManager native query to send the appropriate native SQL CREATE UNIQUE INDEX commands. A @Startup @Singleton bean is useful for this sort of task if you're using EJB3.1. See the PostgreSQL documentation for the structure of pg_catalog.pg_index. To just check if an index of a given name exists, run:

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

Note that the above query does nothing to verify it's the index you expect, but you can do that with some additional checks. Just examine the contents of pg_index after creating the index so you know what to test for. I don't recommend trying to check for any particular value of indpred; just make sure it isn't null.

于 2012-08-19T14:46:36.367 回答