JPA 的 @UniqueConstraint 注释似乎并不能保证唯一性

Posted

技术标签:

【中文标题】JPA 的 @UniqueConstraint 注释似乎并不能保证唯一性【英文标题】:JPA's @UniqueConstraint annotation doesn't seem to guarantee uniqueness 【发布时间】:2014-10-21 22:48:15 【问题描述】:

我有这个代码:

@Table(uniqueConstraints = @UniqueConstraint(columnNames = "name", "color"))
@MappedSuperclass
public abstract class AbstractInstance extends Model 

    @NotNull
    public String name;

    public String color;

    ...

但由于某种原因,@UniqueConstraint 无效 - 我成功地在数据库中放入了具有完全相同名称和颜色的多个实例(当我查询 color='green' AND name='MyName' 时,我得到了多个结果)。难道我做错了什么?我应该做些什么来让这个复合唯一性约束生效吗?

问题的另一个证据可能是,当我查询数据库的 INFORMATION_SCHEMA.CONSTRAINTS 关于我的相关表时,我得到的结果似乎没有提到“名称”和“颜色”是唯一的:

CONSTRAINT_CATALOG | CONSTRAINT_SCHEMA | CONSTRAINT_NAME    | CONSTRAINT_TYPE | UNIQUE_INDEX_NAME | CHECK_EXPRESSION | COLUMN_LIST  | SQL  
------------------------------------------------------------------------------------------------------------------------------------------------------------------------
play               | public            | fkcb0e606fe2f3066d | REFERENTIAL     | PRIMARY_KEY_8     | null         | CONTAINER_ID | ALTER TABLE PUBLIC.UNLABELEDINSTANCE ADD
                   |                   |                    |                 |                   |                  |              | CONSTRAINT PUBLIC.FKCB0E606FE2F3066D FOREIGN
                   |                   |                    |                 |                   |                  |              | KEY(CONTAINER_ID) INDEX
                   |                   |                    |                 |                   |                  |              | PUBLIC.FKCB0E606FE2F3066D_INDEX_C REFERENCES
                   |                   |                    |                 |                   |                  |              | PUBLIC.DATASET(ID) NOCHECK
------------------------------------------------------------------------------------------------------------------------------------------------------------------------
play               | public            | constraint_d7      | PRIMARY KEY     | PRIMARY_KEY_C     | null             | ID           | ALTER TABLE PUBLIC.UNLABELEDINSTANCE ADD
                   |                   |                    |                 |                   |                  |              | CONSTRAINT PUBLIC.CONSTRAINT_D7 PRIMARY KEY(ID)
                   |                   |                    |                 |                   |                  |              | INDEX PUBLIC.PRIMARY_KEY_C

我正在使用:

Java 1.7 通过 maven 依赖项休眠:org.hibernate.javax.persistence:hibernate-jpa-2.0-api:1.0.1.Final(我不知道如何从中推断出 JPA\Hibernate 的版本) 播放框架 1.2.7 H2 数据库(Play Framework 自带的,用于内存数据库)

【问题讨论】:

您是否使用 JPA 生成数据库架构?请显示模式转储。也有可能您将 Hibernate 配置为列名与您在注释中列出的不同。 如何生成模式转储?以及相关的 Hibernate 配置是什么? 在你的 persistence.xml 中是否有一个属性 我的项目中似乎没有 persistence.xml。我认为 Play 框架会在内部处理所有这些事情。 如果你删除了你的数据库,PlayFramework 会重新创建它吗? 【参考方案1】:

指定@UniqueConstraint 的唯一效果是,如果您使用JPA 提供程序的模式生成功能,则会将唯一约束添加到数据库模式中。如果没有,那么它绝对没有效果。

显而易见的推论是,如果您想在访问数据库之前捕获违反唯一约束的行为,则需要在代码中添加验证。

你必须在某个地方有一个 persistence.xml。

https://www.playframework.com/documentation/2.1.0/JavaJPA

如上所述,您需要添加以下属性

Hibernate hbm2ddl.auto possible values and what they do?

【讨论】:

【参考方案2】:

您定义了@UniqueConstaint 的类是@MappedSuperClass。但是派生实体不会继承唯一约束。您要么需要为每个派生实体定义唯一约束,要么使用 orm.xml 文件。

请参阅此答案以获取更多信息:How to use @UniqueConstraint with single table inheritance (JPA)?

此外,正如您问题的其他答案和 cmets 中所述:因为唯一性仅由数据库强制执行,所以 @UniqueConstraint 只有在您使用 JPA 生成架构时才会发挥作用。

【讨论】:

【参考方案3】:

如果您在使用 @UniqueConstraint 注释之前创建了表,您可以删除该表并使用 @UniqueConstraint 注释创建它。在这种情况下,@UniqueConstraint 注释工作正常。

【讨论】:

以上是关于JPA 的 @UniqueConstraint 注释似乎并不能保证唯一性的主要内容,如果未能解决你的问题,请参考以下文章

JPA 的 @UniqueConstraint 注释似乎并不能保证唯一性

如何将@UniqueConstraint 与单表继承(JPA)一起使用?

Heroku spring-jpa UniqueConstraint

Java中的@UniqueConstraint注解

@UniqueConstraint

如何在hbm中做多列UniqueConstraint?