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 中是否有一个属性指定@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)一起使用?